TCPサーバーはLISTEN状態のソケット一つでどうやって複数の接続を捌くのでしょうか？


[RFC793
に書かれている状態遷移図](http://www.atmarkit.co.jp/ait/articles/0402/13/news096_3.html)（原文では[§3.2](https://www.rfc-
editor.org/rfc/rfc793#section-3.2)のFigure6）では、サーバー側は LISTEN ... ESTABLISHED
... CLOSED と遷移していくように書かれています。

リモートエンドポイントを指定せずに LISTEN 状態に入ったサーバーは、クライアントからの接続を受けてリモートエンドポイントを確定し、 ESTABLISH
状態に入ります。 **しかしその後もサーバーは他のエンドポイントからの接続を待ち受けています。**

この流れは「 LISTEN 状態のソケットが1つあり、接続を受けると ESTABLISHED
に遷移する」では説明がつかないように思うのですが、どのように考えるとよいのでしょうか？




> この流れは「 LISTEN 状態のソケットが1つあり、接続を受けると ESTABLISHED  
>  に遷移する」では説明がつかないように思うのですが、どのように考えるとよいのでしょうか？

「コネクション」と「ソケット」の区別をしてください。  
その状態遷移図は「コネクション」の状態を示しているもので、「ソケット」の状態ではありません。

§1.5. Operation

> Concatenated with the network and host addresses from the internet  
>  communication layer, this forms a socket. A pair of sockets uniquely  
>  identifies each connection.

§2.7. Connection Establishment and Clearing

> A local socket may participate in many connections to different  
>  foreign sockets.

ひと組のソケット（つまりローカルのソケットとリモートのソケット）によってコネクションを識別しています。  
ソケットが1つであっても、コネクションが1つであるとは限りません。1つのソケットが複数のコネクションに紐付けられていてもよいのです。




ざっくり言うと、仕様と矛盾しない範囲で工夫して実装されているということですよね。

> しかしその後もサーバーは他のエンドポイントからの接続を待ち受けています。

そもそも、RFC 793 で言及されている TCP のユーザインタフェースは、BSD Socket API
を想定したものではなく、以下のような単純なものです。

  * OPEN
  * SEND
  * RECEIVE
  * CLOSE

RFC に記載されている TCP コネクションの状態遷移図に記載されているイベントも、このインタフェース（コマンド）の通りですよね。

> この流れは「 LISTEN 状態のソケットが1つあり、接続を受けると ESTABLISHED に遷移する」では説明がつかないように思うのですが

RFC 記載のユーザインタフェースには、BSD Scoket API の listen() -> accept()
に相当するものはありませんので、説明がつかないのは当然といえば当然ですね。

実際には、h2so5 さんが回答されているように `ローカルソケットは複数の外部からのソケットに参加することができる`
と記載されていますので、その前提をもとに考えると listen() したソケットが accept() した後に再度接続を待ち受けるという動きは RFC
と矛盾していないというのが分かると思います。

