首頁 > 後端開發 > Python教學 > 當伺服器不發回資料時,為什麼 `socket.recv()` 會停止?

當伺服器不發回資料時,為什麼 `socket.recv()` 會停止?

Patricia Arquette
發布: 2024-11-22 22:33:26
原創
948 人瀏覽過

Why Does `socket.recv()` Stall When the Server Doesn't Send Data Back?

了解套接字行為:為什麼Socket.recv() 在沒有發送資料的情況下停止

Python 套接字與TCP連接一樣,表現為資料流在客戶端和伺服器之間流動。本文深入探討了修改資料傳輸後,socket.recv()呼叫無法傳回資料的原因。

Echo Server 範例

考慮官方文件中的 Python echo 伺服器範例。此伺服器偵聽傳入連線、接收資料並回顯給客戶端。以下程式碼片段複製了原始伺服器行為:

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()
登入後複製

更改伺服器行為

將程式碼修改為不將資料傳回客戶端時會出現此問題:

while True:
    data = conn.recv(1024)
    if not data: break
conn.close()
登入後複製

在這段修改後的程式碼中,while循環不斷地從客戶端接收數據,但伺服器卻從不發送數據後退。這會導致客戶端在 socket.recv() 呼叫處無限期地停止。

理解通訊流程

TCP 套接字不維護一對一關係不同端點上的發送和接收呼叫之間。相反,協定定義了通訊規則。在這種情況下,原始的回顯伺服器實作了一個規則,即伺服器將回顯接收到的數據,直到客戶端關閉連線。

當伺服器行為發生變更時,規則實際上已被修改。伺服器現在只接收資料並丟棄它,直到客戶端關閉連線。伺服器永遠不會將資料傳回客戶端。

調整客戶端行為

要使用修改後的伺服器,客戶端必須調整其行為。由於伺服器不再主動發送數據,客戶端認為收到回數據表示連線已完成。為了實現這一點,客戶端應該關閉其連接的傳出端,以向伺服器發出訊號已完成發送資料。然後,客戶端可以執行多個 recv 呼叫來處理傳入資料的任何潛在碎片。

更新的程式碼

以下是伺服器和客戶端的更新程式碼,遵守修改後的規則通訊:

伺服器:

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()
登入後複製

客戶端:

import socket

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:
    buf = s.recv(1024)
    if not buf:
        break
    data += buf
s.close()
print('Received', repr(data))
登入後複製

透過了解基於流的本質TCP套接字並相應地調整通訊規則,可以解決socket.recv()在沒有資料的情況下停止的問題已發送。

以上是當伺服器不發回資料時,為什麼 `socket.recv()` 會停止?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板