python實現tcp伺服器和客戶端(socket)
阿新 • • 發佈:2018-12-29
python實現tcp伺服器和客戶端(socket)
1.socket模組
socket是什麼
socket最初是為了同一主機上的應用程式建立的,使得一個程式與另外一個程式之間可以通訊,也就是所謂的程序間通訊,有兩種型別的socket:基於檔案和麵向網路的。
-
UNIX 套接字是我們所講的套接字的第一個家族,並且擁有一個“家族名字”AF_UNIX(又名 AF_LOCAL,在 POSIX1.g 標準中指定),它代表地址家族(address family):UNIX。包括 Python 在內的大多數受歡迎的平臺都使用術語地址家族及其縮寫 AF;其他比較舊的統可能會將地址家族表示成域(domain)或協議家族(protocol family),並使用其縮寫 PF 而非 AF。類似地,AF_LOCAL(在 2000~2001 年標準化)將代替 AF_UNIX。然而,考慮到後向相容性,很多系統都同時使用二者,只是對同一個常數使用不同的別名。Python 本身仍然在使用 AF_UNIX。
-
第二種型別的套接字是基於網路的,它也有自己的家族名字 AF_INET,或者地址家族:因特網。另一個地址家族 AF_INET6 用於第 6 版因特網協議(IPv6)定址。此外,還有其他的地址家族,這些要麼是專業的、過時的、很少使用的,要麼是仍未實現的。在所有的地址家族之中,目前 AF_INET 是使用得最廣泛的。
2.建立tcp時間戳伺服器
建立tcp伺服器和客戶端的基本流程
from socket import *
from time import ctime
HOST = ''
PORT = 31188
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)#初始化
tcpSerSock.bind(ADDR)
tcpSerSock.listen()#監聽埠
while True:
print('witing for connection')#等待cilent的連線
tcpCliSock, addr = tcpSerSock.accept()
print('connected from:{}'.format(addr))
while True:
data = tcpCliSock.recv(BUFSIZ) .decode()#接受的字元
if not data:
break
tcpCliSock.send(ctime().encode())#傳送字元
tcpCliSock.close()
tcpSerSock.close()#關閉埠
- 建立socket前必須使用socket.socket()函式,socket_family 為AF_INET即為第二類的socket面向網路的,還有一種AF_INET6 面向ipv6網路。socket_type為AF_STREAM或AF_DGARM。現在建立tcp伺服器也就是第一種。
- bind()繫結埠,listen() 監聽埠,
- accept()被動接受客戶端的連線(阻塞),並返回一個獨立的客戶端socket,這是一個獨立的佇列,用來和即將到來的訊息進行交換。
- recv()接受訊息但是接收到的訊息為bytes,使用decode()解碼為str格式,對應的send()函式也應該用encode()進行編碼,才能正常的通訊。
- 最後將兩個佇列accept和syn佇列都關閉,結束通訊。
3.tcp客戶端
from socket import *
HOST = '127.0.0.1'
PORT = 31188
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
while True:
sdata = input('> ')
if not sdata:
break
tcpCliSock.send(sdata.encode())
rdata = tcpCliSock.recv(BUFSIZ).decode()
if not rdata:
break
print(rdata)
tcpCliSock.close()
- 需要注意的是HOST為127.0.0.1,這也是localhost即為本機的地址,如果要兩個主機通訊的話則需要設定為目標主機的ip。
4.執行tcp服務端和客戶端
- 服務端
- 客戶端
這樣就實現了通訊。得到了伺服器的時間戳。
5.實際應用
分散式主機經常會因為時間不同步問題而產生問題,我們就可以用python寫簡單的指令碼,實現簡單的時間同步指令碼。