ホームページ >バックエンド開発 >Python チュートリアル >サーバーが受信データをエコーバックしない場合、TCP ソケットの動作はどのように変化しますか?

サーバーが受信データをエコーバックしない場合、TCP ソケットの動作はどのように変化しますか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-03 03:36:13262ブラウズ

How Does TCP Socket Behavior Change When a Server Doesn't Echo Back Received Data?

TCP ソケット通信: ソケットの動作を理解する

Python で TCP ソケットを操作する場合、これらのソケットのストリームベースの性質を理解することが重要です接続。送信操作と受信操作の間の 1 対 1 の関係とは異なり、データ フローは実装されたプロトコルによって決まります。

単純なエコー サーバーの次のコード スニペットを考えてみましょう。

import socket

HOST = ''
PORT = 50007

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

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

元の形式では、このコードはクライアントとの接続を確立し、クライアントからのデータを待機し、クライアントが切断されるまでデータをエコー バックします。ループは繰り返し繰り返され、サーバーは各受信メッセージを受信して​​応答します。

ただし、サーバーがクライアントにデータを送り返すステップを除外するようにコードを変更するとします。

import socket

HOST = ''
PORT = 50007

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

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

このシナリオでは、recv メソッドの動作が変更されます。変更されたサーバーは、クライアントとの接続を確立すると、データを待ちます。ただし、データは送信されないため、recv メソッドは無期限にブロックされます。 recv への 2 回目の呼び出しは決して発生しないため、サーバーはクライアントの切断を認識できません。

この動作を理解するには、TCP ソケットがデータ ストリームとして動作することを覚えておくことが重要です。データの送信と受信は相互に直接結びついておりません。通信を管理するルールは、実装されたプロトコルによって決まります。元のコードでは、プロトコルはサーバーがクライアントから受信したデータをエコー バックするように指示していました。

修正により、プロトコルが変更されます。サーバーはクライアントからデータを受信するだけで、それを破棄します。クライアントはデータ送信後の応答を期待しますが、変更されたサーバーは沈黙したままになります。この問題を解決するには、クライアントは送信接続を閉じてデータの送信が完了したことを明示的に示す必要があります。これが発生すると、サーバーは空の recv 呼び出しを受信し、切断として解釈し、「OK」メッセージの送信を開始します。

さらに、実際のシナリオでは、データ パケットが送信中に断片化する可能性があります。これに対処するために、より堅牢なクライアント実装では、すべてのデータが受信されるまで複数の recv 呼び出しが実行されます。

以下は、これらに対処するサーバーおよびクライアント コードの更新バージョンです。問題:

サーバー:

import socket

HOST = ''
PORT = 50007

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

while True:
    data = s.recv(1024)
    if not data: break
    s.sendall(b'ok')
    s.shutdown(socket.SHUT_WR)
    s.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()

これらの変更を実装することで、次のことが保証されます。サーバーとクライアント間の通信は意図したとおりに動作し、切断を認識し、データの断片化を処理します。

以上がサーバーが受信データをエコーバックしない場合、TCP ソケットの動作はどのように変化しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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