Rubyの非同期タスクスケジューラーを自作するにあたり、ネットワーク通信、特にソケットについて理解を深めておきたいと考えた。
経験上まずは手を動かしてみるのがベストだと考えている。以下の素晴らしい記事が見つかったので自分でもやってみる。
手を動かした中で個人的にメモっておきたいところを残す。
Socketとは
Socketは、ネットワークはプログラムが外部のネットワークと通信する際のインターフェイスとして使われるもの。ファイルとして抽象化される。
Socket通信の種類の例
- インターネット通信
- UDP (dgram型)
- TCP (stream型)
- プロセス間通信(UNIX domain socket通信)
- UNIX domain socket dgram (dgram型)
- UNIX domain socket stream (stream型)
dgramとstreamの違い
関連記事を貼る。
memo. sreamの方が信頼性という面では優れている。
サーバーとなるプロセスがデータを受信する手順
以下インターネット通信の場合。unix domain socket通信の場合は、「ポート」が「ファイル」になる。
- ソケットを生成する(複数可能)
- ソケットを初期化する
- そのソケットを一つのポートにバインドする
- [stream型のソケットの場合のみ]ソケットを通してポートをリッスンする。
- クライアントからのデータ受信を無限ループする
- IO::select で、ソケットに張り付き、データが到着したソケットを検知する。
- [ストリーム型のソケットの場合のみ]
Socket#accept
で、そのソケットのクライアントとのconnectionをアクセプトする - そのソケットに入っているデータを読み出す。
- [ストリーム型のソケットの場合のみ]
Socket#close
で、connectionをclose する。
終了後は、ソケットをcloseすることを忘れずに。
クライアントとなるプロセスがデータを送信する手順
- ソケットを生成する
- ソケット経由でデータを書き込む。
- ストリーム通信のソケットの場合には、
Socket#connect(送信先)
でコネクションを確立してから、Socket#write(データ)
を使用する。 - データグラム通信のソケットの場合には、
Socket#send(データ, 送信先)
を使用する。
- ストリーム通信のソケットの場合には、
Rubyでの実装
を参照すると良い。以下の通信が実装されている。
- internet❎dgram
-
Socket.new(:INET, :DGRAM)
でソケット生成 -
UDPSocket.new
でもソケット生成可能
-
- internet❎stream
-
Socket.new(:INET, :DGRAM)
でソケット生成 -
TCPSocket.new
でもソケット生成可能 -
TCPServer.new
でもソケット生成+listenが可能
-
- unix_domain_socket❎dgram
-
Socket.new(:UNIX, :DGRAM)
でソケット生成
-
- unix_domain_socket❎stream
-
Socket.new(:UNIX, :DGRAM)
でソケット生成 -
UNIXSocket.new
でもソケット生成が可能 -
UNIXServer.new
でもソケット生成+listenが可能
-
Ref.
メモ
- ストリーム型のsocketには、
Socket#write
追記
https://docs.ruby-lang.org/ja/latest/class/Socket.html#I_ACCEPT_NONBLOCK に書いてあった。
ソケットオブジェクトを生成する汎用的な方法として Socket.new がありますが、以下のようなより便利なメソッドがあります。
- TCP のクライアントソケット Socket.tcp TCPSocket.open
- TCP のサーバソケット Socket.tcp_server_loop, Socket.tcp_server_sockets, TCPServer.open
- UNIX socket のクライアントソケット Socket.unix UNIXSocket.open
- UNIX socket のサーバソケット Socket.unix_server_loop, Socket.unix_server_socket, UNIXServer.open
また、クライアントソケットは Addrinfo#connect で、サーバソケットを Addrinfo#bind や Addrinfo#listen で作ることもできます。