ホームページ >バックエンド開発 >Python チュートリアル >Python ソケット サーバーからエコーするデータを削除すると、`socket.recv()` が後続の呼び出しで何も返さないのはなぜですか?

Python ソケット サーバーからエコーするデータを削除すると、`socket.recv()` が後続の呼び出しで何も返さないのはなぜですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-27 03:37:22938ブラウズ

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

Python ソケット: データ戻り動作の影響を理解する

当初、公式ドキュメントの Python エコー サーバーの例は問題なく機能しました。ただし、クライアントへのデータの返送を排除するためにコードを変更すると、問題が発生しました。 socket.recv() メソッドの 2 回目の呼び出しでは何も返されませんでした。

異なる実装、異なる結果

ドキュメントの元のコードでは while ループが使用されていました。

conn.sendall(data)

この行は、クライアントが接続の終了を閉じるまで、サーバーが受信したデータをクライアントにエコーバックすることを暗示しています。

修正したコードでは、動作が次のように変更されました。

break

conn.recv(1024) メソッドが 2 回目に呼び出されるとき、メソッドはすぐに終了し、クライアントが使用できるデータは残りません。

TCP ストリームの性質

この動作を理解するには、次のようにします。 TCP ストリームの性質を把握することが不可欠です。クライアントとサーバーの操作間に直接の相関関係はなく、連続的なフローでデータを送信します。さらに、プロトコルは基礎となる通信ルールを決定します。

元のコードでは、プロトコルは、クライアントが発信接続を閉じるまで、サーバーが受信した各データ パケットをエコーすることを指示していました。閉じると、サーバーはソケットを閉じます。

変更されたプロトコルとクライアントの調整

変更されたコードでは、クライアントが受信するまでサーバーが受信データを破棄する新しいプロトコルが導入されました。発信接続を閉じました。その後、サーバーは「ok」を送信してソケットを閉じます。

クライアントをこの新しいプロトコルで動作させるには、次のことが必要でした。

  1. へのクライアントの発信接続を閉じる完了を示します。
  2. データの潜在的な断片化を考慮して複数の recv() 呼び出しを実装します。

更新されたサーバーとクライアント

次の更新されたコード サンプルは、改訂されたプロトコル実装を示しています:

サーバー:

インポートソケット</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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。