ホームページ >バックエンド開発 >Python チュートリアル >Python ソケット サーバーからエコーするデータを削除すると、`socket.recv()` が後続の呼び出しで何も返さないのはなぜですか?
Python ソケット: データ戻り動作の影響を理解する
当初、公式ドキュメントの Python エコー サーバーの例は問題なく機能しました。ただし、クライアントへのデータの返送を排除するためにコードを変更すると、問題が発生しました。 socket.recv() メソッドの 2 回目の呼び出しでは何も返されませんでした。
異なる実装、異なる結果
ドキュメントの元のコードでは while ループが使用されていました。
conn.sendall(data)
修正したコードでは、動作が次のように変更されました。
break
TCP ストリームの性質
この動作を理解するには、次のようにします。 TCP ストリームの性質を把握することが不可欠です。クライアントとサーバーの操作間に直接の相関関係はなく、連続的なフローでデータを送信します。さらに、プロトコルは基礎となる通信ルールを決定します。
元のコードでは、プロトコルは、クライアントが発信接続を閉じるまで、サーバーが受信した各データ パケットをエコーすることを指示していました。閉じると、サーバーはソケットを閉じます。
変更されたプロトコルとクライアントの調整
変更されたコードでは、クライアントが受信するまでサーバーが受信データを破棄する新しいプロトコルが導入されました。発信接続を閉じました。その後、サーバーは「ok」を送信してソケットを閉じます。
クライアントをこの新しいプロトコルで動作させるには、次のことが必要でした。
更新されたサーバーとクライアント
次の更新されたコード サンプルは、改訂されたプロトコル実装を示しています:
サーバー:
インポートソケット</p> <p>HOST = ''<br>PORT = 50007 <br>s =ソケット.ソケット(ソケット.AF_INET, ソケット.SOCK_STREAM)<br>s.setsockopt(ソケット.SOL_SOCKET, ソケット.SO_REUSEADDR, 1)<br>s.bind((ホスト、 PORT))<br>s.listen(1)</p> <p>conn, addr = s.accept()<br>print('Connected by', 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()
クライアント:
インポートソケット</p> <p>HOST = 'localhost'<br>PORT = 50007<br>s =ソケット.socket(socket.AF_INET,ソケット.SOCK_STREAM)<br>s.connect((HOST, PORT))<br>s.sendall (b「こんにちは、 world')<br>s.shutdown(socket.SHUT_WR)<br>data = b''<br>while True:</p> <pre class="brush:php;toolbar:false">data = conn.recv(1024) if not data: break
s.close()
print('Received' , repr(data))
これらの改訂された実装では、サーバーは受信データを効率的に破棄し、クライアントが閉じた後に応答を受信できるようにします。
以上がPython ソケット サーバーからエコーするデータを削除すると、`socket.recv()` が後続の呼び出しで何も返さないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。