建立兩個py文件,分別打開兩個cmd界面,即可進行通信。服務器端運用多進程,連續不斷的處理從客戶端接收到的數據;客戶端通過一個list不斷給客戶端發送數據。
(每個連接都必須創建新線程(或進程)來處理,否則,單線程在處理連接的過程中,無法接受其他客戶端的連接。)本例中,多進程其實沒有起到作用。
代碼以及解釋如下:
# 服務器端
# 1 創建套接字,綁定套接字到當地地址,然后開始監聽連接。就是socket,bind,listen。 # 2 進入循環,不斷接受客戶端的連接請求,然后接收傳來的數據,當然也可以發送給對方數據。就是accept一個連接,然后recv數據。 # 3 接收完畢可以關閉套接字,close。 # 這個過程的偽代碼如下:
ss=socket() #創建服務器套接字
ss.bind() #把本地地址綁到套接字上
ss.listen() #監聽連接
inf_loop: #服務器無限循環
cs=ss.accept() #接受客戶端的連接
comm._loop: #通信循環
cs.recv()/cs.send() #對話
cs.close() #關閉客戶套接字
ss.close() #關閉服務器套接字
#客戶端 # 1 創建套接字,然后連接遠端地址,socket ,connect。 # 2 建立連接之后開始發送數據。Send(data),當然可以從緩沖區讀取服務器發來的數據。Recv(BUFF) # 3 完畢后,關閉套接字。Close # 偽代碼如下: cs=socket() #創建客戶套接字 cs.connect() #嘗試連接服務器 comm._loop: #通信循環 cs.send()/cs.recv() #對話 cs.close() #關閉套接字
#socket服務器端程序 import socket import time from multiprocessing import Process #多進程和多線程一樣的用法 def tcplink(sock1,addr1): #新建一個函數,用來接收客戶端發來的信息 print('Accept new connection......') sock1.send(b'welcom') #若連接建立成果,服務器給客戶端發送一個welcome while 1: #服務器持續接收客戶端發送過來的數據,直到服務器收到exit時,退出不在接收數據 data = sock1.recv(1024) #接收數據 time.sleep(1) #延時1s '''data為客戶端發送給服務器的數據,服務器給客戶端發送hello,%data ,全部轉為utf-8編碼''' sock1.send(('hello,%s'%data.decode('utf-8')).encode('utf-8')) if not data or data.decode('utf-8') == 'exit': break sock1.close() #連接關閉 print('connection form %s is close....'%addr1) if __name__ == "__main__": s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #建立一個套接字 '''監聽端口127.0.0.1表示客戶端和服務器必須都為本機才能運行。 我們要綁定監聽的地址和端口。服務器可能有多塊網卡,可以綁定到 某一塊網卡的IP地址上,也可以用0.0.0.0綁定到所有的網絡地址,還 可以用127.0.0.1綁定到本機地址。127.0.0.1是一個特殊的IP地址,表 示本機地址,如果綁定到這個地址,客戶端必須同時在本機運行才能連接 ,也就是說,外部的計算機無法連接進來。端口號需要預先指定。因為我 們寫的這個服務不是標准服務,所以用9999這個端口號。請注意,小於1024 的端口號必須要有管理員權限才能綁定:''' s.bind(('127.0.0.1', 9999)) #綁定端口 s.listen(1) #同時接收連接的最大數量 print('Waiting for connecting......') while 1: #服務器通過一個循環來一直接收來之客戶端發送的信息 sock,addr = s.accept() #s.accept返回兩個數據 t = Process(target=tcplink,args=(sock,addr)) #多線程 t.start() #開啟多線程
#socket客戶端程序 #同chenhang001.py import socket s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #新建一個套接字 s.connect(('127.0.0.1',9999)) #建立連接,為什么是雙括號 print(s.recv(1024).decode('utf-8')) #打印接收到的數據 #發送數據,定義一個list, for data111 in [b'chenhang',b'wangyadan',b'wuhankejidaxue',b'wuchangfenxiao']: s.send(data111) print(s.recv(1024).decode('utf-8')) # for a in range(100): # s.send(b(a)) s.send(b'exit') #發送exit字符,服務器退出接收數據
