web-dev-qa-db-ja.com

ソケットプログラミング-listen()とaccept()の違いは何ですか?

このチュートリアル を読んで、ソケットプログラミングについて学びました。 listen()およびaccept()システムコールは両方とも同じことを行うようです。つまり、ブロックし、socket()システムで作成されたソケットにクライアントが接続するのを待ちます。コール。このために2つの別個のステップが必要なのはなぜですか?なぜ1つのシステムコールを使用しないのですか?

ところで、私はこの質問をグーグルで検索し、同様の質問を見つけましたが、満足のいく答えはありませんでした。たとえば、accept()によってソケットが作成されることがわかっているので、socket()がソケットを作成するというのは意味がありません。

17
Zen Hacker

listen()関数は、基本的に内部ソケット構造にフラグを設定し、パッシブリスニングソケットとしてソケットをマークします。これは、accept onを呼び出すことができます。バインドされたポートを開き、ソケットがクライアントからの接続の受信を開始できるようにします。

accept()関数は、リスニングソケットに次の着信接続を受け入れ、その接続のソケット記述子を返すように要求します。したがって、ある意味では、accept()doesは、着信接続用にlisten()に使用するソケットではなく、ソケットを作成します。

18

それはすべて歴史的なセットアップの一部です。 listenは、次のaccept呼び出しのためにソケットを準備します。また、Listenでは、バックログ(システムで受け入れられる接続の数)をセットアップし、プログラムが実際にそれらを受け入れることができるようになるまで待つことができます。バックログがいっぱいになった後に来るすべてのものは、すぐにシステムによって拒否されます。 listenはブロックしませんが、acceptは次の接続が来るまでブロックします(ソケットが非ブロックモードでない限り)。明らかに、これは2つの別個の関数である必要はありません-accept()関数はlistenが行うすべてを実行できると考えられます。

20
SergeyA

上記の2つの答えは、受け入れと聞くの違いを明確に述べています。他の質問に答えるために-なぜ2つの別個の機能が必要なのでしょうか?

1つのユースケースは、例えばポートがまだ使用可能/アクセス可能かどうかだけをテストする場合は、ポートをリッスンしてから、接続を受け入れずにポートを閉じることでテストできます。

たとえば https://github.com/coolaj86/golang-test-port は、ポートの可用性をテストするためにリッスンコールを使用します。

4
J Aamish