ソケット通信
ネットワーク通信をファイルのように扱う API。 Berkeley ソケット(1983 年、4.2BSD)が事実上の標準。
サーバ側#
socket() ソケットを作る
bind() アドレスとポートに結び付ける
listen() 接続待ち状態にする
accept() 接続を受け入れる(新しいソケットが返る)
read/write データをやり取りする
close()クライアント側#
socket()
connect()
read/write
close()ファイル記述子としての抽象#
ソケットはファイル記述子。
read / write がそのまま使える。
「すべてはファイル」という Unix の設計が、
ネットワークにも適用されている。
おかげで既存の道具(パイプ、リダイレクト、select)が
そのまま使える。
多重化#
同時に多数の接続を扱う方法。
| 方式 | 特徴 |
|---|---|
| 接続ごとにプロセス | 単純。重い |
| 接続ごとにスレッド | やや軽い。1 万接続で破綻 |
select / poll |
1 スレッドで多数を監視。 の走査 |
epoll / kqueue |
。Linux / BSD |
| io_uring | 非同期 I/O を一括投入 |
select は毎回全記述子を走査するので、
接続数が増えると遅くなる。
epoll は準備できたものだけ返すので定数時間。
これが C10K 問題(1 万接続を同時に扱う)の解決策で、 nginx や Node.js のイベント駆動モデルの基礎になっている。
参考文献#
- James F. Kurose, Keith W. Ross. Computer Networking: A Top-Down Approach, 8th ed. Pearson, 2021.
- W. Richard Stevens, Bill Fenner, Andrew M. Rudoff. UNIX Network Programming, Vol. 1, 3rd ed. Addison-Wesley, 2003.
- Dan Kegel. The C10K problem. http://www.kegel.com/c10k.html