クライアントソケットのバッファサイズとして1024を使用しているとします。
recv(1024)
サーバーが私に送信したいメッセージが2024バイトで構成されているとしましょう。ソケットが受信できるのは1024バイトだけです。他の1000バイトはどうなりますか?
または
1.)が正しい場合...私が時間を決定する方法はありますか?recvデータは戻る前に待機する必要がありますか、それともシステムによって決定されますか? (つまり、ソケットに5秒間待機してから、さらにデータを待機するように停止するように指示できますか?)
更新:次のコードがあると仮定します:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], port))
s.send('Hello, world')
data = s.recv(1024)
print("received: {}".format(data))
s.close()
サーバーが1024バイトを超えるサイズのデータを送信するとします。変数 "data"にすべてのデータ(1024バイト目以降のデータを含む)が含まれることを確認できますか?それについて確信が持てない場合、変数「data」にサーバーから送信されたすべてのデータが(1つまたは多くのステップで)確実に含まれるようにするには、コードをどのように変更する必要がありますか?
プロトコルによって異なります。 UDPのようないくつかのプロトコルはメッセージを送信し、recv
ごとに正確に1つのメッセージが返されます。 TCP具体的には、具体的にはいくつかの要因があります。TCPはストリーム指向であり、現在未処理の送信/受信データの量などにより、 、回線上のパケットの損失/再配列、データの確認応答の遅延、およびNagleアルゴリズム(一部の小さな送信を数百ミリ秒遅延)の場合、クライアントとサーバー間の会話が進むにつれてその動作は微妙に変化する可能性があります。
受信者が知っているのは、バイトのストリームを取得していることだけです。 1から、recvで完全に要求されたバッファサイズまで何でも取得できます。一方の送信呼び出しともう一方の受信呼び出しの間には1対1の相関関係はありません。
メッセージの境界を把握する必要がある場合は、それを上位レベルのプロトコルまで把握する必要があります。 HTTPを例にとります。\r\n区切りのヘッダーで始まり、クライアントが受信すると予想される残りのバイト数が含まれます。\r\nが次に来るバイト数を正確に知っているため、クライアントはヘッダーの読み取り方法を知っています。 RESTfulプロトコルの魅力の1つは、HTTPベースであり、他の誰かがすでにこれを理解していることです。
一部のプロトコルでは、NULを使用してメッセージを区切ります。その他の変数データのカウントを含む固定長のバイナリヘッダーがある場合もあります。私は zeromq が好きです。TCPの上に堅牢なメッセージングシステムがあります。
Receiveで何が起こるかについての詳細...
recv(1024)
を実行すると、6つの可能性があります
受信データはありません。 recv
は、受信データがあるまで待機します。タイムアウトを設定することで変更できます。
部分的な受信データがあります。あなたはその部分をすぐに得るでしょう。残りはバッファリングされているか、まだ送信されておらず、さらに取得するために別の受信を実行します(同じルールが適用されます)。
利用可能な1024バイト以上があります。そのデータの1024を取得し、残りは別の受信を待機しているカーネルにバッファーされます。
反対側はソケットをシャットダウンしました。 0バイトのデータを取得します。 0は、そのソケットでこれ以上データを取得しないことを意味します。しかし、データを要求し続けると、0バイトを取得し続けます。
反対側はソケットをリセットしました。例外が発生します。
その他の奇妙なことが起こっており、例外が発生します。