Linuxにおけるソケットプログラミングの基礎

Linux環境でのネットワーク通信を実現するためには、ソケットAPIが基本的な役割を果たします。これはTCPやUDPといったプロトコルを利用して、プロセス間でデータを送受信するためのインターフェースです。

ソケットの概念

ソケットは、ネットワーク通信を行うためのエンドポイントとして機能し、OSによって管理されるファイルディスクリプタと関連付けられます。各ソケットは「プロトコル・ローカルIP・ローカルポート・リモートIP・リモートポート」の5要素(五つ組)で一意に識別されます。

バイトオーダーの扱い

ネットワーク通信では、異なるアーキテクチャ間でもデータ解釈を統一するため、ビッグエンディアン形式(ネットワークバイトオーダー)が標準です。ホストマシンがリトルエンディアンの場合、送受信前に変換が必要です。

バイトオーダー変換関数

  • htonl(x):32ビット整数をホスト→ネットワーク順に変換
  • htons(x):16ビット整数をホスト→ネットワーク順に変換
  • ntohl(x):32ビット整数をネットワーク→ホスト順に変換
  • ntohs(x):16ビット整数をネットワーク→ホスト順に変換

アドレス構造体

汎用構造体sockaddrは内部で使われることが多く、実際のプログラミングではIPv4専用のsockaddr_inが主流です。

struct sockaddr_in {
    sa_family_t     family;      // アドレスファミリ(例: AF_INET)
    in_port_t       port;        // ポート番号(ネットワークバイトオーダー)
    struct in_addr  addr;        // IPv4アドレス(ネットワークバイトオーダー)
    char            padding[8];  // アラインメント用パディング
};

struct in_addr {
    uint32_t s_addr;
};

ソケット生成関数

int sock = socket(AF_INET, SOCK_STREAM, 0);

第1引数:AF_INET(IPv4)、AF_INET6(IPv6)など
第2引数:SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)、SOCK_RAW(生IP)など
成功時はファイルディスクリプタ、失敗時は-1を返します。

IPアドレス変換関数

#include <arpa/inet.h>

// 文字列 → バイナリ(ネットワーク順)
inet_pton(AF_INET, "192.168.1.10", &addr.sin_addr);

// バイナリ(ネットワーク順)→ 文字列
inet_ntop(AF_INET, &addr.sin_addr, buffer, sizeof(buffer));

構造体初期化の例

struct sockaddr_in endpoint;
char ip_str[INET_ADDRSTRLEN];

memset(&endpoint, 0, sizeof(endpoint));
endpoint.family = AF_INET;
endpoint.port = htons(8080);

if (inet_pton(AF_INET, "10.0.0.1", &endpoint.addr) != 1) {
    perror("Invalid address");
    return -1;
}

inet_ntop(AF_INET, &endpoint.addr, ip_str, sizeof(ip_str));
printf("Configured IP: %s\n", ip_str);

タグ: linux socket ネットワークプログラミング

8月12日 15:44 投稿