python代碼實現tcp客戶端和服務端通信演示

1.TCP介紹

TCP協議,傳輸控制協議(英語:Transmission Control Protocol,縮寫爲 TCP)是一種面向連接的、可靠的、基於字節流的傳輸層通信協議,由IETF的RFC 793定義。TCP通信需要經過創建連接、數據傳送、終止連接三個步驟。

2.TCP特點

1. 面向連接

通信雙方必須先建立連接才能進行數據的傳輸,雙方都必須爲該連接分配必要的系統內核資源,以管理連接的狀態和連接上的傳輸。雙方間的數據傳輸都可以通過這一個連接進行。完成數據交換後,雙方必須斷開此連接,以釋放系統資源。

這種連接是一對一的,因此TCP不適用於廣播的應用程序,基於廣播的應用程序請使用UDP協議。

2. 可靠傳輸

1)TCP採用發送應答機制

TCP發送的每個報文段都必須得到接收方的應答才認爲這個TCP報文段傳輸成功

2)超時重傳

發送端發出一個報文段之後就啓動定時器,如果在定時時間內沒有收到應答就重新發送這個報文段。

TCP爲了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據包就被假設爲已丟失將會被進行重傳。

3)錯誤校驗

TCP用一個校驗和函數來檢驗數據是否有錯誤;在發送和接收時都要計算校驗和。

4) 流量控制和阻塞管理

流量控制用來避免主機發送得過快而使接收方來不及完全收下。

3.TCP的通信架構

udp通信模型中,在通信開始之前,一定要先建立相關的鏈接,才能發送數據,類似於生活中,"打電話"

4.python代碼實現TCP客戶端發送,接收數據通信

TCP通信與UDP的很大不同就是首先要建立連接,然後才能進行通信,數據的傳輸。如下創建TCP客戶端。

from socket import *
# 1.創建套接字

tcp_socket = socket(AF_INET,SOCK_STREAM)

# 2.準備連接服務器,建立連接
serve_ip = input("請輸入服務器ip:")
serve_port = int(input("請輸入對應的端口號:"))  # 端口要是int類型,所有要轉換

tcp_socket.connect((serve_ip,serve_port))  # 連接服務器,建立連接,參數是元組形式

# 3.準備需要傳送的數據
send_data = input("請輸入要發送的數據:")
tcp_socket.send(send_data.encode("gbk"))  #用的是send方法,不是sendto

#4.從服務器接收數據
tcp_remsg = tcp_socket.recv(1024) #注意這個1024byte,大小根據需求自己設置
print(tcp_remsg.decode("gbk"))  #如果要亂碼可以使用tcp_remsg.decode("gbk")

#4.關閉連接
tcp_socket.close()

上面創建TCP客戶端後,使用網絡調試助手,開啓TCP Server模式,將其當成服務器,啓動。

注意,服務器必須先啓動,否則報錯,無法建立連接

5.TCP實現服務器

想要完成一個tcp服務器的功能,需要的流程如下:

  1. socket創建一個套接字
  2. bind綁定ip和port
  3. listen使套接字變爲可以被動鏈接
  4. accept等待客戶端的鏈接
  5. recv/send接收發送數據
from socket import  *

# 1.創建套接字
tcp_server = socket(AF_INET,SOCK_STREAM)

# 2.綁定ip,port
address = ('',3434)
tcp_server.bind(address)

# 3.啓動被動連接
# 使用socket創建的套接字默認的屬性是主動的,使用listen將其變爲被動的,這樣就可以接收別人的鏈接了
tcp_server.listen(128)  #這個值主要決定了同一時刻有多少個客戶端可以連接

# 4.創建接收
# 如果有新的客戶端來鏈接服務器,那麼就產生一個新的套接字專門爲這個客戶端服務
# client_socket用來爲這個客戶端服務,相當於的tcp_server套接字的代理
# tcp_server_socket就可以省下來專門等待其他新客戶端的鏈接
# 這裏clientAddr存放的就是連接服務器的客戶端地址
client_socket, clientAddr = tcp_server.accept()


#5.接收對方發送過來的數據
recv_msg = client_socket.recv(1024)#接收1024給字節,這裏recv接收的不再是元組,區別UDP
print("打印接收的數據:",recv_msg)
#6.發送數據給客戶端
send_data = client_socket.send("這是給您的回覆".encode("gbk"))

#7.關閉套接字
#關閉爲這個客戶端服務的套接字,只要關閉了,就意味着爲不能再爲這個客戶端服務了,如果還需要服務,只能再次重新連
client_socket.close()

 測試結果下,使用網絡調試助手,配置稱客戶端,連接服務器通信

  1. tcp服務器一般情況下都需要綁定,否則客戶端找不到這個服務器
  2. tcp客戶端一般不綁定,因爲是主動鏈接服務器,所以只要確定好服務器的ip、port等信息就好,本地客戶端可以隨機
  3. tcp服務器中通過listen可以將socket創建出來的主動套接字變爲被動的,這是做tcp服務器時必須要做的
  4. 當客戶端需要鏈接服務器時,就需要使用connect進行鏈接,udp是不需要鏈接的而是直接發送,但是tcp必須先鏈接,只有鏈接成功才能通信
  5. 當一個tcp客戶端連接服務器時,服務器端會有1個新的套接字,這個套接字用來標記這個客戶端,單獨爲這個客戶端服務
  6. listen後的套接字是被動套接字,用來接收新的客戶端的鏈接請求的,而accept返回的新套接字是標記這個新客戶端的
  7. 關閉listen後的套接字意味着被動套接字關閉了,會導致新的客戶端不能夠鏈接服務器,但是之前已經鏈接成功的客戶端正常通信。
  8. 關閉accept返回的套接字意味着這個客戶端已經服務完畢
  9. 當客戶端的套接字調用close後,服務器端會recv解堵塞,並且返回的長度爲0,因此服務器可以通過返回數據的長度來區別客戶端是否已經下線
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章