【TCP/IP】虚拟机环境下,TCP协议的简单实现以及[Errno 61] Connection refused的排障

环境:

Mac:VIM8+YouCompleteMe+Python3

Parallels下CentOS7:VIM8+YouCompleteMe+Python3

目的:

 Mac为Client,CentOS7为Server.Server监听端口,并对Client的TCP请求响应

实现:

Parallels的网络设置为共享网络

Mac的地址为10.211.55.2 CentOS7的地址为10.211.55.10,子网掩码都为ff:ff:ff:00

Mac的脚本:Python中定义了socket类,可以很方便的实现TCP协议。Client端只要知道Server端的IP和port,并用connect方法联系到服务器就可以接受数据了。recv方法接受的实际是一个文件/比特流对象,因此需要进行解码。

           

#!/usr/bin/env python3
#coding=utf-8
import socket
import time
#创建一个socket的类,socket.AF_INET指的是IPV4,SOCK_STREAM指的是TCP协议,UDP协议对应socket_DRAM
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#连接PC服务器的端口,参数是(IP/域名,端口)
ServerPort=('10.211.55.10',9999)
# connect_ex是connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
s.connect_ex(ServerPort)

#接受服务器的消息,限制接受大小为1kb=1024b=128KB
while True:
    try:
    #接受消息,并打印,解码用utf-8
        print("Local:OK?")
        print(s.recv(1024).decode('utf-8'))
        time.sleep(1)
#发送消息,注意用二进制的数据传输,因为发送的实际是一个数据流
        data=(('Client'.encode('utf-8')))
        s.send(data)
    except:
        break
print("Connection is closed by Server")

CentOS7:服务器端创建一个socket类,并对端口进行绑定和监听;随后用accept方法接受来自客户端的connect请求,并得到IP和端口。随后也和客户端一样,用recv和send方法接受和发送数据,注意也是文件或者数据流,是二进制的对象。

#!/usr/bin/env python3
#coding=utf-8
import socket 
import os
import threading
import time

#定义一个接受和发送数据的函数,5次发送后即在服务器端强行关闭连接。
def tcplink(sock,addr):
    print("Accept the new connection from %s:%s"%addr)
    sock.send(b"Welcome!Here is the Sever @10.211.55.10.")
    n=int(5)
    while n>0:
        data=sock.recv(1024)
        time.sleep(1)
        sock.send(('Server==>I have heard you.{:s}:{:d},{:d} talks remaining\n'.format(addr[0],addr[1],n-1)).encode('utf-8'))
        sock.send(('Server==>You said:{:s}\n'.format(data.decode('utf-8'))).encode('utf-8'))
        n-=1
    sock.close()
    print('Connection from %s is close.'%addr[0])

#创建socket类的实例,并绑定和监听,闲置最大连接数为2.        
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('10.211.55.10',9999))
s.listen(2)
print('server is listening,waiting for connection......')

#创建一个新的进程来处理客户端的请求
while True :
    sock,addr=s.accept()
    #注意accept方法得到的是一个socket类和一个端口地址的元组。用print命令很容易验证。
    print(sock,addr)
    try:
        t=threading.Thread(target=tcplink,args=(sock,addr))
        tname=t.name
        print('Now {:s} is running for connection from {:s}'.format(tname,addr[0]))
        t.start()
    except :
        print("Server is block")

先启动服务器端:

root-> ./TCPserver.py 
server is listening,waiting for connection......

客户端执行结果如下:

root-> ./TCPClient-10.211.55.10.py 
Local:OK?
Welcome!Here is the Sever @10.211.55.10.
Local:OK?
Server==>I have heard you.10.211.55.2:53387,4 talks remaining

Local:OK?
Server==>You said:Client

Local:OK?
Server==>I have heard you.10.211.55.2:53387,3 talks remaining

Local:OK?
Server==>You said:Client

Local:OK?
Server==>I have heard you.10.211.55.2:53387,2 talks remaining

Local:OK?
Server==>You said:ClientClient

Local:OK?
Server==>I have heard you.10.211.55.2:53387,1 talks remaining

Local:OK?
Server==>You said:ClientClient

Local:OK?
Server==>I have heard you.10.211.55.2:53387,0 talks remaining

Connection is closed by Server

客户端执行完毕后,服务器端:

root-> ./TCPserver.py 
server is listening,waiting for connection......
 ('10.211.55.2', 53387)
Now Thread-1 is running for connection from 10.211.55.2
Accept the new connection from 10.211.55.2:53387
Connection from 10.211.55.2 is close.

遇见的问题:

1 出现了服务器拒绝连接的问题

   s.connect(ServerPort)
ConnectionRefusedError: [Errno 61] Connection refused

  首先ping服务器,可以连通,说明路由没有问题;在客户端用curl探测端口,发现22端口正常,9999端口被拒绝。

root-> curl 10.211.55.10:22
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
curl: (56) Recv failure: Connection reset by peer

root-> curl 10.211.55.10:9999
curl: (7) Failed to connect to 10.211.55.10 port 9999: Connection refused

说明可能是防火墙阻挡了TCP的请求。然后开始坑爹的CentOS防火墙设置,最终才搞定:

#关闭firewalls并禁止开机启动
root->systemctl stop firewalld.service
root->systemctl disable firewalld.service

#安装iptables.service,注意不是iptables命令
root->yum install iptables.service

#配置iptables,必须先安装iptables.service,否则不能生产iptables这个文件
root->vim /etc/sysconfig/iptables
#加上这条:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 9999 -j ACCEPT
systemctl enable iptables.service
systemctl start iptables.service

#编辑selinux的选项
vim /etc/selinux/config
#注释掉SELINUXTYPE=targeted

2 虚拟机因为频繁的开关,导致时钟不同步。

在编译或者安装一些文件时易出错。

#!/usr/bin/bash
ntpdate cn.pool.ntp.org
if [ x$? = x0 ] ;then
	echo "os time is OK"	
	else 
	echo "os time is NOK"
fi
hwclock --systohc --localtime
if [ x$? = x0 ] ;then
	echo "mainboard time is OK"	
	else 
	echo "mainboard time is NOK"
fi

 

你可能感兴趣的:(TCP/IP)