はじめに

ソケット通信について学習したことをメモ。

ソケット通信の概要

1. ソケット通信とは

ソケット通信とは、ネットワークを介してプロセス間通信(IPC)を行うための仕組み。
TCP/IP プロトコルを使用してデータを送受信することが一般的。

socket, bindなどのインターフェースはPOSIXレベルで定義されている。

2. ソケットの種類

ソケットの種類 説明
ストリームソケット (SOCK_STREAM) TCP に基づくソケット。信頼性のある通信を提供。
データグラムソケット (SOCK_DGRAM) UDP に基づくソケット。接続レスで高速な通信を提供。
RAWソケット (SOCK_RAW) IP パケットレベルの通信を行う低レベルのソケット。
シーケンスパケットソケット (SOCK_SEQPACKET) メッセージ指向で順序制御された通信を提供。

3. ソケット通信の基本フロー (TCP)

  1. サーバー側

    • ソケット作成 (socket())
    • アドレスとポートのバインド (bind())
    • クライアントからの接続待機 (listen())
    • 接続受け入れ (accept())
    • データの送受信 (send(), recv())
    • 接続の終了 (close())
  2. クライアント側

    • ソケット作成 (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 で簡単にネットワーク通信を実装可能。
  • ソケットオプションを適切に設定すると、より柔軟な通信が実現できる。