簡體   English   中英

Python套接字不接收而不發送

[英]Python socket not receiving without sending

我從python文檔中復制了echo服務器示例,並且工作正常。 但是,當我編輯代碼時,它不會將數據發送回客戶端,因此第二次調用時socket.recv()方法不會返回。

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(b'ok')
conn.close()

在python文檔的原始版本中,while循環略有不同:

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

客戶代碼:

import socket

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
s.close()
print('Received', repr(data))

接收和發送操作的數量必須匹配,因為它們阻塞了。 這是您的代碼的流程圖:

Server listen 
Client connect 
Server receive (this waits until a message arrives at the server) [1] 
Client send 'Hello world' (received by [1])
Server receive (because there was data received) [2]
Client receive [3]

由於服務器和客戶端現在被阻止,因此沒有程序可以繼續。

解決方法是刪除客戶端的接收呼叫,因為您刪除了服務器的發送呼叫。

TCP套接字是數據流。 一側的發送呼叫與另一側的接收呼叫之間沒有一對一的關聯。 根據您實現的協議,存在更高級別的相關性。 在原始代碼中,規則是服務器將完全發送接收到的消息,直到客戶端關閉連接的傳入端為止。 然后,服務器關閉插座。

隨着您的更改,規則也隨之更改。 現在,服務器一直在接收和丟棄數據,直到客戶端關閉連接的傳入端為止。 然后服務器發送“ ok”並關閉套接字。

使用第一個規則的客戶端掛起,因為它在關閉套接字之前期望數據。 如果要使用此新服務器規則,則必須關閉套接字的輸出端以告知服務器已完成,然后才能獲取返回數據。

我已經更新了客戶端和服務器以關閉連接的某些部分,並且還讓客戶端執行多個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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM