[解決済み] ソケットAPIのaccept()関数はどのように動作するのですか?
質問
ソケットAPIは、TCP/IPおよびUDP/IP通信のデファクトスタンダードです(つまり、私たちが知っているネットワークコードです)。しかし、その中心的な機能の 1 つである
accept()
は少し不思議です。
半官半民の定義を借りると
accept() はサーバーサイドで使用されます。 からの新しいTCP接続を作成するために、受信した着信の試行を受け取ります。 から新しい TCP 接続を作成するために受信した試みを受け入れ を受信し、そのソケットに関連付けられた新しい ソケットを作成します。 アドレスのペアに関連付けられた新しいソケットを作成します。
言い換えると
accept
は新しいソケットを返し、それを通してサーバーは新しく接続されたクライアントと通信することができます。古いソケット(その上で
accept
が呼び出された)古いソケットは、同じポートで開かれたまま、新しい接続を待ちます。
どのようにして
accept
はどのように機能するのでしょうか?どのように実装されているのでしょうか?このトピックには多くの混乱があります。多くの人は、accept が新しいポートを開き、それを通してクライアントと通信すると主張します。しかし、新しいポートは開かれないので、これは明らかに真実ではありません。実際には、同じポートを通じて異なるクライアントと通信することができます。複数のスレッドが
recv
を呼び出した場合、データはどこに行くかをどのように知るのでしょうか?
クライアントのアドレスがソケットディスクリプタに関連付けられ、データが送られてくるたびに
recv
を介してデータが来るたびに、正しいソケットにルーティングされるのだと思いますが、よくわかりません。
この仕組みの内部を徹底的に解説してもらえると助かります。
どのように解決するのですか?
あなたの混乱は、ソケットがサーバーIPとサーバーポートによって識別されると考えていることにあります。 実際には、ソケットは4つの情報によって一意に識別されます。
Client IP : Client Port
そして
Server IP : Server Port
したがって、サーバー IP とサーバー ポートは、受け入れたすべての接続で一定ですが、クライアント側の情報は、すべてがどこに向かっているのかを追跡することを可能にするものです。
物事を明確にするための例
にサーバがあるとします。
192.168.1.1:80
と二つのクライアントがあるとします。
10.0.0.1
と
10.0.0.2
.
10.0.0.1
ローカルポートで接続を開く
1234
で接続を開き、サーバに接続する。 これで、サーバーには次のように識別されるソケットが1つできました。
10.0.0.1:1234 - 192.168.1.1:80
現在
10.0.0.2
はローカルポートで接続を開始します。
5678
で接続を開き、サーバに接続する。 これで、サーバーは以下のように識別された2つのソケットを持つことになります。
10.0.0.1:1234 - 192.168.1.1:80
10.0.0.2:5678 - 192.168.1.1:80
関連
-
[解決済み] 複数のdocker-composeプロジェクト間の通信
-
[解決済み】WindowsのコマンドラインからTCPとUDPのポートを閉じる方法
-
[解決済み] Go で HTTP レスポンスに文字列としてアクセスする
-
[解決済み] Centos 7でiptablesを使うにはどうしたらいいですか?[クローズド]
-
[解決済み】Javaで現在のマシンのIPアドレスを取得する
-
[解決済み] protobufとgRPCの比較
-
[解決済み] ソケットAPIのaccept()関数はどのように動作するのですか?
-
[解決済み] Wireshark localhostのトラフィックキャプチャ [終了しました]。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン