
私の理解では、TCPはデータの塊を取り、それをセグメントTCP経由で送信されるセッション。
ここで、クライアントである私が、サーバーに送信したいデータのチャンクを 2 つ持っているとします。各チャンクは 3 つのセグメントに分割され、合計 6 つのセグメントが形成されますA
。B
これらの 6 つのセグメントをインターネット経由で送信しますが、サーバーがそれらを受信する順序を保証することはできません。幸いなことに、TCP サーバーは順序が乱れたセグメントを並べ替えてくれます。
ただし、私のアプリケーションでは、チャンクA
と は完全に独立しているため、すべてのセグメントが受信された場合にサーバーがセグメントB
を待機したり、その逆を行ったりすることは望ましくありません。実際には、チャンクと に対して 2 つの独立した TCP セッションが必要です。A
B
A
B
クライアントとサーバーが並行して独立した TCP セッションを持つことは可能ですか? TCP ヘッダー エントリを見ると、「セッション番号」がありません。異なる送信元ポートまたは宛先ポートを使用する必要がありますか?
答え1
もちろん、同じクライアントとサーバーの間で 2 つの並行した独立した TCP セッションを確立できます。そうしないと、たとえば、Web ブラウザーは HTML ページと画像、または Web サーバーから同時に 2 つの画像を取得できなくなります。
TCPセッションの識別子は「セッション番号」ではなくタプルである。(ローカル アドレス、ローカル ポート、リモート アドレス、リモート ポート)少なくとも 1 つが異なる限り、それは別の TCP セッションになります。
したがって、質問に対する答えは、はい、異なる送信元ポートまたは宛先ポートを使用する必要があります。同じ送信元ポートと宛先ポートを使用しようとすると、TCP スタックは接続を拒否します (エラー EADDRINUSE が表示されます)。これはすべて、ローカル アドレスとリモート アドレスが全体的に同じであることを前提としています。
しかし、これは通常、心配する必要はありません。通常、TCP イニシエーター (クライアント) は特定のポートにバインドする必要はありません。bind()
を呼び出す前にを呼び出さないことで、カーネルが送信元ポートを自動的に選択できるようにしますconnect()
。カーネルは、2 番目の接続に対して別の送信元ポートを選択するようにします。
答え2
受け入れられた回答は正しく、質問に対する回答ですが、質問は複数の TCP ストリームを使用する以外の回答がある問題に対処しています。
あなたが説明している「ヘッドオブラインブロッキング」問題は、クイックUDPインターネット接続(QUIC)プロトコルの背後にある動機の1つです。このウェブキャストQUIC がこの問題やその他の問題をどのように解決するかに興味がある場合は、Google の QUIC に関する記事をご覧ください。
もちろん、Wikipedia の QUICあまりにも。