TCP和并發服務器
與UDP不同的是,他是一個面向連接的,可靠的數據傳輸協議
TCP通信比較復雜
先寫一個TCP服務器,一般步驟如下:
1、首先是要創建一個socket套接字:socket()
2、服務器一般是需要一個固定的IP地址和固定端口號,服務器就要綁定這個IP地址和端口號:bind()
3、客戶端連接服務器是是有一定的數量(允許最大連接數)的,而這個數量是服務器設定的:listen()
4、上面3步是做被連接的準備,這一步是來接受客戶端的數據,在接受數據之前,服務器還是需要接受客戶端的socket套接字和IP地址:accept()
5、只有服務器和客戶端綁定相同的IP地址,服務器和客戶端才可以互相接收數據和發送數據,常理來想,服務器是一只被開啟的,也是一直接受數據,所以在接受數據的過程中,我們需要無限循環:recv()
6、如果我們要發送數據給客戶端,客戶端也需要綁定上面的地址,然后需要調用相應的函數send()
import socket # TCP # 創建一個服務器socket套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 服務器的IP地址和端口號 address = ( " 127.0.0.1 " , 9999 ) # 服務器綁定地址 server_socket.bind(address) # 設置服務器的最大連接數 server_socket.listen(1 ) # 創建一個等待連接的客戶端socket套接字,accept()函數會返回兩個值,可以自行打印 client_socket, address = server_socket.accept() # 服務器需要不停的接受客戶端的發來的數據 while True: """ 以防客戶端連接失敗,需要檢測異常 無論是接受數據還是發送數據,我們需要將數據統一編碼和解碼 """ try : data = client_socket.recv(2048).decode( " UTF-8 " ) # 數據處理 print ( " 服務器接受的數據: " , data) # 服務器接受的數據:我是一個客戶端 client_socket.send( " 我是一個服務器 " .encode( " UTF-8 " )) except : break
再寫一個TCP客戶端,一般步驟如下:
1、首先是要創建一個socket套接字:socket()
2、客戶端一般是不需要一個固定的IP地址和固定端口號,連接服務器的時候系統會自動分配端口號
3、客戶端連接服務器必須先知道服務器的IP地址和端口號,然后在連接服務器:connect()
4、上面3步是做連接的準備,這一步是來發送客戶端的數據:send()
5、客戶端也可以一直接受服務器發來的數據,所以在接受數據的過程中,我們需要無限循環:recv()
import socket # 客戶端需要創建一個套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 客戶端需要連接服務器,必須先知道服務器的IP地址和端口號 address = ( " 127.0.0.1 " , 9999 ) # 連接服務器 client_socket.connect(address) # 這個數據是將要發送的數據 data = " 我是一個客戶端 " client_socket.send(data.encode( " UTF-8 " )) while True: """ 以防服務器中斷退出,需要檢測異常 無論是接受數據還是發送數據,我們需要將數據統一編碼和解碼 """ try : data = client_socket.recv(2048).decode( " UTF-8 " ) # 數據處理,這里打印出來并且將數據發回客戶端 print ( " 客戶端接受的數據: " , data) except : break
?并發服務器,這里我只介紹多線程服務器,進程和線程是差不多的)
在TCP服務器的原有基礎上增加一個線程,再將監聽數增加為5,就可以允許5個客戶端線程同時訪問,并且可同時發送和接受數據
import socket from threading import Thread # TCP # 創建一個服務器socket套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 服務器的IP地址和端口號 address = ( " 127.0.0.1 " , 9999 ) def net_connect(): try : # 服務器綁定地址 server_socket.bind(address) # 設置服務器的最大連接數 server_socket.listen(5 ) except : return # 創建線程 th = Thread(target= recv_data) th.start() def recv_data(): # 服務器需要不停的接受客戶端的發來的數據 while True: """ 以防客戶端連接失敗,需要檢測異常 無論是接受數據還是發送數據,我們需要將數據統一編碼和解碼 """ # 創建一個等待連接的客戶端socket套接字,accept()函數會返回兩個值,可以自行打印 client_socket, address = server_socket.accept() try : data = client_socket.recv(2048).decode( " UTF-8 " ) # 數據處理 print ( " 服務器接受的數據: " , data) client_socket.send( " 我是一個服務器 " .encode( " UTF-8 " )) except : break net_connect()
?
在TCP客戶端上也增加一個線程,然后同時運行多次這個客戶端程序:
import socket # 客戶端需要創建一個套接字 from threading import Thread client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 客戶端需要連接服務器,必須先知道服務器的IP地址和端口號 address = ( " 127.0.0.1 " , 9999 ) def net_connect(): try : # 連接服務器 client_socket.connect(address) except : return th = Thread(target= recv_data) # th.setDaemon(True) th.start() def recv_data(): # 這個數據是將要發送的數據 data = " 我是一個客戶端 " client_socket.send(data.encode( " UTF-8 " )) while True: """ 以防服務器中斷退出,需要檢測異常 無論是接受數據還是發送數據,我們需要將數據統一編碼和解碼 """ try : data = client_socket.recv(2048).decode( " UTF-8 " ) # 數據處理,這里打印出來并且將數據發回客戶端 print ( " 客戶端接受的數據: " , data) except : break net_connect()
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
