サーバーはどのクライアントポートに送信するかをどのように調べますか?

サーバーはどのクライアントポートに送信するかをどのように調べますか?

私が理解したところ、クライアントが接続要求をすると、次のことが起こります。

  1. サーバーは特定のポート番号にバインドされます。ポート番号は常に受信プロセスに関連付けられています。サーバーだけが着信接続を受信して​​いるため、クライアント側でバインドする必要はありません。
  2. サーバーは引き続きこのポート番号をリッスンします。
  3. connect()クライアントが要求を送信します。
  4. サーバーは承認要求を使用しますaccept()。サーバーがクライアント要求を受け入れると、カーネルは追加操作のためにサーバーにランダムなポート番号を割り当てます。これは、send()サーバーreceive()の同じポート番号が送受信に使用できず、古いポートがまだ新しい接続を受信して​​いるためです。

これらすべてを考慮すると、サーバーはどのクライアントがどのポートでデータを受信して​​いるかをどのように知ることができますか?クライアントは送信元ポートと宛先ポートを含むTCPセグメントを送信することを知っているので、サーバーはそのセグメントの送信元ポートを宛先ポートとして使用しますが、サーバーはどのポートを見つけるためにそのポートを見つけるのですか?うんaccept()

ベストアンサー1

これはパケットのTCP(またはUDPなど)ヘッダーの一部です。したがって、クライアントが指示するので、サーバーは調べます。これは、クライアントのIPアドレス(IPヘッダーの一部)を見つける方法と似ています。

たとえば、すべてのTCPパケットにはIPヘッダー(最小ソースIP、宛先IP、およびプロトコル[TCP]を含む)が含まれています。次にTCPヘッダー(ソースポートと宛先ポートなどを含む)が続きます。

カーネルがリモートIPが10.11.12.13(IPヘッダーから)でリモートポートが12345(TCPヘッダーから)のSYNパケット(TCP接続の開始)を受信すると、リモートIPとポートがわかります。 SYN | ACKを再送信します。 ACKが受信されると、listenコールは接続に確立された新しいソケットを返します。

TCPソケットは、4つの値(リモートIP、ローカルIP、リモートポート、ローカルポート)で一意に識別されます。少なくとも1つが異なる限り、複数の接続/ソケットを持つことができます。

通常、ローカルポートとローカルIPは、サーバープロセスへのすべての接続に対して同じです(たとえば、sshdへのすべての接続はlocal-ip:22にあります)。リモートコンピュータが複数の接続を作成する場合、各接続は異なるリモートポートを使用します。したがって、リモートポート以外のすべては同じですが、大丈夫です。 4つのポートのうち1つだけが異なる必要があります。

たとえば、wirehsark を使用してパケットを表示でき、すべてのデータにタグが付けられます。以下は強調表示されたソースポートです(デコードされたパケットで強調表示され、下部の16進ダンプに注意してください)。

Wireshark は TCP SYN パケットを表示します。

おすすめ記事