ソケットとは
ソケットは、ネットワークにおける通信の終端点(エンドポイント)を識別し、接続を確立するための抽象的な概念とメカニズムです。特に、BSD系
UNIXを起源とするAPI群は「BSDソケット」や「バークレーソケット」とも呼ばれ、
C言語でのネットワークプログラミングにおいて重要な役割を果たします。
ソケットは、単なる通信端点ではなく、通信を抽象化する概念やAPI全体を包含するものです。
1983年にリリースされた4.2BSD
UNIXで初めてAPIとして実装されて以来、ネットワークインターフェースの
デファクトスタンダードとして広く普及しています。
BSDソケットのインターフェース
BSDソケットは、異なるホスト間や同一コンピュータ上の
プロセス間の通信を可能にします。通信媒体は
オペレーティングシステムの実装に依存しますが、TCP/IPを利用する際にはほぼ必須のインターフェースとなります。このインターフェースは当初、
カリフォルニア大学バークレー校で
UNIX向けに開発されましたが、現在ではほぼ全ての
オペレーティングシステムに実装され、
インターネット接続の標準的なインターフェースとなっています。
プログラマの視点から見ると、ソケットインターフェースは主に3つのレベルで利用できます。最も基本的なレベルは「RAWソケット」であり、自由度の高い通信制御が可能ですが、高度な専門知識が求められます。通常のアプリケーション開発では、より抽象化されたsocketインターフェースを利用することが一般的です。
socketインターフェースは、様々なネットワークプロトコルを抽象化しており、プロトコルファミリーとソケットタイプに基づいてグループ化されています。例えば、
IPv4を表す`AF_INET`や、
UNIXドメインソケットを表す`AF_
UNIX`などがあります。ソケットタイプには、ストリーム型の`SOCK_STREAM`や、データグラム型の`SOCK_DGRAM`などがあり、これらの組み合わせによって利用する
トランスポート層プロトコルが決まります。
BSDソケットを利用する際には、以下の
ヘッダファイルをインクルードする必要があります。
`
`: ソケットの中核となる関数とデータ構造を定義
``: `AF_INET`と`AF_INET6`アドレスファミリを定義。IPアドレスやTCP/UDPポート番号が含まれる
``: `AF_UNIX`アドレスファミリを定義。ローカルプロセス間通信で使用
``: IPアドレスを数値として操作する関数を定義
``: ホスト名やプロトコル名を数値アドレスに変換する関数を定義
TCP
TCPはコネクション指向のプロトコルであり、信頼性の高い通信を提供します。TCPソケットを生成するには、`socket()`関数で`AF_INET`または`AF_INET6`と`SOCK_STREAM`を指定します。
1. `socket()`関数でTCPソケットを生成
2. `bind()`関数でソケットを特定のポートにバインド
3. `listen()`関数で接続要求の待機を開始
4. `accept()`関数で接続を受け入れ、クライアントとの通信を開始
5. `send()`/`recv()`または`write()`/`read()`関数でデータの送受信
6. `close()`関数でソケットをクローズ
TCPクライアントの設定
1. `socket()`関数でTCPソケットを生成
2. `connect()`関数でサーバに接続
3. `send()`/`recv()`または`write()`/`read()`関数でデータの送受信
4. `close()`関数でソケットをクローズ
UDP
UDPはコネクションレスのプロトコルであり、データの到達保証はありません。TCPに比べてオーバーヘッドが少なく、高速な通信が可能です。
1. `socket()`関数でUDPソケットを生成
2. `bind()`関数でソケットを特定のポートにバインド
3. `recvfrom()`関数でデータを受信
UDPクライアントの設定
1. `socket()`関数でUDPソケットを生成
2. `sendto()`関数でデータを送信
UNIXドメインソケットは、同一コンピュータ上のプロセス間で通信するためのメカニズムです。IPアドレスとポート番号の代わりにファイルパスを使用します。
主要な関数
`socket()`: ソケットを作成
`gethostbyname()`/`gethostbyaddr()`: ホスト名やアドレスからホスト情報を取得
`connect()`: サーバに接続
`bind()`: ソケットにアドレスをバインド
`listen()`: 接続要求を待ち受け
`accept()`: クライアントからの接続を受け入れる
ブロッキングとノンブロッキング
ソケットには、ブロッキングモードとノンブロッキングモードがあります。ブロッキングモードでは、処理が完了するまで関数が戻りませんが、ノンブロッキングモードでは即座に戻ります。ブロッキング/ノンブロッキングの切り替えには、`fcntl()`や`ioctl()`関数を使用します。
注意点
`socket()`で確保したリソースは、`close()`で明示的に解放する必要があります。再試行を伴う実装では、リソースリークに注意が必要です。
標準規格
ソケットインターフェースの標準定義は、POSIX標準(IEEE Std. 1003.1-2001)に記載されています。IPv6拡張については、RFC 3493とRFC 3542に詳細が記述されています。
参考文献
IEEE Std. 1003.1-2001 Standard for Information Technology -- Portable Operating System Interface (POSIX).
Open Group Technical Standard: Base Specifications, Issue 6, December 2001.
ISO/IEC 9945:2002
RFC 3493
RFC 3542
関連項目
コンピュータネットワーク
Transmission Control Protocol (TCP)
User Datagram Protocol (UDP)
Winsock
外部リンク
socket(2) – JM Project Linux System Calls マニュアル
connect(2) – JM Project Linux System Calls マニュアル
bind(2) – JM Project Linux System Calls マニュアル
listen(2) – JM Project Linux System Calls マニュアル
accept(2) – JM Project Linux System Calls マニュアル
socket(7) – JM Project Linux Overview, Conventions and Miscellanea マニュアル
tcp(7) – JM Project Linux Overview, Conventions and Miscellanea マニュアル
udp(7) – JM Project Linux Overview, Conventions and Miscellanea マニュアル
* Porting Socket Applications to Winsock - Win32 apps | Microsoft Docs