首頁  >  文章  >  後端開發  >  為什麼刪除從 Python Socket 伺服器回顯的資料會導致 `socket.recv()` 在後續呼叫中不回傳任何內容?

為什麼刪除從 Python Socket 伺服器回顯的資料會導致 `socket.recv()` 在後續呼叫中不回傳任何內容?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-27 03:37:22921瀏覽

Why Does Removing Data Echoing from a Python Socket Server Cause `socket.recv()` to Return Nothing on Subsequent Calls?

Python Socket:了解資料回傳行為的影響

最初,官方文件中的 Python echo 伺服器範例運作完美。然而,在修改程式碼以消除將資料發送回客戶端後,出現了問題。第二次呼叫 socket.recv() 方法沒有回傳。

不同的實現,不同的結果

文件中的原始程式碼使用了一個while 迴圈:

conn.sendall(data) pre><br>這一行暗示伺服器會將收到的資料回顯給客戶端,直到客戶端關閉其連線。 <p>在修改後的程式碼中,行為變更如下:<br></p><pre class="brush:php;toolbar:false">break

當第二次呼叫conn.recv(1024) 方法時,它會立即終止,沒有留下可用的資料客戶端。

TCP 流的本質

要理解這種行為,必須掌握 TCP 流的本質。它們以連續流傳輸數據,客戶端和伺服器操作之間沒有直接關聯。此外,協定決定了底層的通訊規則。

在原始程式碼中,協定規定伺服器將回顯它收到的每個資料包,直到客戶端關閉其傳出連線。關閉後,伺服器將關閉其套接字。

修改後的協議和客戶端調整

修改後的程式碼引入了一個新協議,伺服器將丟棄傳入的數據,直到客戶端關閉其傳出連接。隨後,伺服器將發送“ok”並關閉其套接字。

為了讓客​​戶端使用這個新協議,有必要:

  1. 關閉客戶端的傳出連線指示完成。
  2. 實作多個recv() 呼叫以解決資料中潛在的碎片問題

更新的伺服器和客戶端

以下更新的程式碼範例示範了修訂後的協定實作:

伺服器:

導入套接字<p>HOST = ''<br>PORT = 50007 <br>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>s.setsock .SOL_SOCKET, socket.SO_REUSEADDR, 1)<br>s.bind((主持人, PORT))<br>s.listen(1)</p><p>conn, addr = s.accept()<br>print('連接者', addr)</p><p>while True:</p><pre class="brush:php;toolbar:false">data = conn.recv(1024)
if not data: break

conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()

客戶端:

導入插座

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(HOST, PORTet.SOCK_STREAM)
s.connect(HOST, PORT)) (你好, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:

data = conn.recv(1024)
if not data: break

s.close()
print('已收到' , repr(data))

透過這些修改後的實現,伺服器有效地丟棄傳入的數據,允許客戶端在關閉後接收其回應。

以上是為什麼刪除從 Python Socket 伺服器回顯的資料會導致 `socket.recv()` 在後續呼叫中不回傳任何內容?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn