【TCP/IP】虛擬機器環境下,TCP協議的簡單實現以及[Errno 61] Connection refused的排障
阿新 • • 發佈:2019-01-06
環境:
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......
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('10.211.55.10', 9999), raddr=('10.211.55.2', 53387)> ('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