はじめに
ソケット通信について学習したことをメモ。
ソケット通信の概要
1. ソケット通信とは
ソケット通信とは、ネットワークを介してプロセス間通信(IPC)を行うための仕組み。
TCP/IP プロトコルを使用してデータを送受信することが一般的。
socket, bindなどのインターフェースはPOSIXレベルで定義されている。
2. ソケットの種類
| ソケットの種類 | 説明 |
|---|---|
| ストリームソケット (SOCK_STREAM) | TCP に基づくソケット。信頼性のある通信を提供。 |
| データグラムソケット (SOCK_DGRAM) | UDP に基づくソケット。接続レスで高速な通信を提供。 |
| RAWソケット (SOCK_RAW) | IP パケットレベルの通信を行う低レベルのソケット。 |
| シーケンスパケットソケット (SOCK_SEQPACKET) | メッセージ指向で順序制御された通信を提供。 |
3. ソケット通信の基本フロー (TCP)
-
サーバー側
- ソケット作成 (
socket()) - アドレスとポートのバインド (
bind()) - クライアントからの接続待機 (
listen()) - 接続受け入れ (
accept()) - データの送受信 (
send(),recv()) - 接続の終了 (
close())
- ソケット作成 (
-
クライアント側
- ソケット作成 (
socket()) - サーバーへ接続 (
connect()) - データの送受信 (
send(),recv()) - 接続の終了 (
close())
- ソケット作成 (
各メソッドのイメージ(サーバー側)
socket
ソケットの作成。ソケットは、Linux上の位置(filepathやIPアドレス+ポートのような)は指定しないで作成。
Linux関数の返り値は、file descriptor。 つまり、書き込んだり読み込んだりできるもの。
Linuxの提供するsocket関数のインターフェースは下記。
int socket(int domain, int type, int protocol);
具体的な通信の方式は、domain, type, protocolのタプルに対して定義されるが、protocolはほぼ1固定なので、domainとtypeのタプルで決まる。
| 実際の通信 | domain | protocol |
|---|---|---|
| TCP | AF_INET | SOCK_STREAM |
| UDP | AF_INET | SOCK_DGRAM |
| UNIXドメインソケット | AF_UNIX | SOCK_DGRAM |
4. ソケット通信の基本コード (Python)
TCP サーバーの例
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("0.0.0.0", 12345))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
print(f"接続: {addr}")
client_socket.send(b"Hello, Client!")
client_socket.close()
TCP クライアントの例
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("127.0.0.1", 12345))
message = client_socket.recv(1024)
print(message.decode())
client_socket.close()
5. UDP 通信の基本コード
UDP サーバー
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("0.0.0.0", 12345))
while True:
data, addr = server_socket.recvfrom(1024)
print(f"受信: {data.decode()} from {addr}")
server_socket.sendto(b"Hello, Client!", addr)
UDP クライアント
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.sendto(b"Hello, Server!", ("127.0.0.1", 12345))
data, addr = client_socket.recvfrom(1024)
print(data.decode())
client_socket.close()
6. ソケットオプションの設定例
| オプション | 説明 |
|---|---|
SO_REUSEADDR |
使用済みのアドレスをすぐに再利用 |
SO_KEEPALIVE |
接続が生きているか定期的に確認 |
TCP_NODELAY |
小さなデータ送信時の遅延を抑制 |
SO_BROADCAST |
UDP のブロードキャスト送信を許可 |
7. まとめ
- TCP は信頼性のあるストリーム通信に適し、UDP は軽量でリアルタイム性の高い通信に適する。
socketライブラリを利用することで、Python で簡単にネットワーク通信を実装可能。- ソケットオプションを適切に設定すると、より柔軟な通信が実現できる。