たとえば、「a」と「b」をまったく異なるパケットで送信すると、クライアントはそれを「ab」と読み取ります。それは一度だけ起こりますが、それはゲームで本当の問題を引き起こします.
あなたは TCP の基本的な性質を見失っていると思います。TCP はストリーム プロトコルであり、パケット プロトコルではありません。TCP は、送信者のデータ境界を尊重も保持もしません。別の言い方をすれば、TCP は送信した「パケット」を自由に結合 (または分割!) し、受信側で任意の方法で提示できます。TCP が尊重する唯一の制限は次のとおりです。バイトが配信される場合、送信されたのと同じ順序で配信されます。(そして、Nagle についてこれを変更するものは何もありません。)
したがって、サーバー上でsend
(またはwrite
) を 2 回呼び出すと、次の 6 バイトが送信されます。
"packet" 1: A B C
"packet" 2: D E F
クライアント側は、次のバイト シーケンスのいずれかrecv
(または) である可能性があります。read
ABC / DEF
ABCDEF
AB / CD / EF
あなたのアプリケーションが送信者の 間の境界の知識を必要とする場合、write
その情報を保存して送信するのはあなたの責任です。
他の人が言ったように、それについては多くの方法があります。たとえば、情報の各量の後に改行を送信できます。これは (部分的に) HTTP、FTP、SMTP がどのように機能するかです。
データとともにパケット長を送信できます。これの一般化された形式は、「タイプ、長さ、値」の TLV と呼ばれます。固定長タイプ フィールド、固定長フィールド、および任意長の値を送信します。このようにして、値全体を読み取り、次の TLV の準備が整ったことがわかります。
送信するすべてのパケットの長さが同じになるように調整できます。
他にも解決策はあると思いますので、ご自身で考えていただければと思います。しかし、最初にこれを認識しなければなりません: TCP は、アプリケーション パケットをマージまたは分割することができます。バイトの配信順序は信頼できますが、他には何もありません。