Linux socket programming

C言語でサーバとクラアントの作成をする

ソケット操作の関数

ソケットを作る socket
ソケットに名前をつける bind
接続を受け付ける listen
接続を受け入れる accept
接続を要求する connect
データを受け取る recv
データを送る send
ソケットの入出力を停止する shutdown
ソケットを閉じる close

ソケットを作る:socket (クライアントとサーバで使用)

エラー処理も含めたソケットの製作例

int sd;
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        return (-1);
}

解説

#include<sys/socket.h>
int socket(int domain, int type, int protocol);
domain
AF_INET IPv4
AF_INET IPv6
AF_UNIX コンピュータ内のプロセス通信用
type
SOCK_STREAM TCP
SOCK_DGRAM UDP
protocol

引数protocolには通信プロトコルを示すプロトコル番号を指定します。0を指定すればdomainとtypeで指定した通信領域とソケット型から決まる規定のプロトコルが決まるため、通常は0を指定します。

ソケットに名前を付ける:bind(クライアントとサーバで使用)

サーバで使用する場合、サーバ側のアドレスやポートの設定になります。クライアントで使用する場合、クライアント側のアドレスやポートの設定になります。bindを使用しない場合、IPアドレスは接続に使用できるIPアドレス、ポート番号はテンポラリポートが自動的に割り当てられるため、一般的にクライアントプログラムではbindを使用しません。

int sd;

/* struct sockaddr_in型のsaを定義 */
struct sockaddr_in sa;

/* saの先頭からsizeof(sa)分を0で埋める */
memset (&sa, 0, sizeof(sa));

/* 通常はAF_INETを指定 */
sa.sin_family = AF_INET;

/* ホストバイト順序で表現された16ビット整数(80)をネットワークバイト順序に変換 */
sa.sin_port = htons(80);

/* ホストバイト順序で表現された32ビット整数をネットワークバイト順序に変換 */
sa.sin_addr.s_addr = htonl(INADDR_ANY);

/* sdはソケット記述子。&saをstruct sockaddr_inからsockaddrへのポインタ型に変換 */
if (bind(sd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
        perror("bind");
        (void) close(sd);
        return (-1);
}