ソケット (BSD)
AF_UNIX アドレスファミリ。同一コンピュータ上で動作するプログラム間のローカルな通信に使用。ネットワーク上では使われない。
単純なTCPサーバの設定は、以下のように行われる。
TCPソケットを生成(socket()呼び出し)
そのソケットを listen(コネクション確立要求待ち受け)ポートにバインド(bind()呼び出し)。bind() を呼び出す前に、sockaddr_in 構造体を宣言し、その中身をクリアし(bzero() または memset())、その sin_family フィールドを AF_INET か AF_INET6 に設定し、sin_port フィールドに listen 対象ポート番号をネットワークバイトオーダで設定する。short int をネットワークバイトオーダに変換するには、htons() 関数を使う。
そのソケットをコネクションの listen に使用するため、listen() を呼び出す。
入ってきたコネクションを accept() 呼び出しで受け付ける。これはコネクションが受信されるまでブロックし、受信したコネクションのソケット記述子を返す。最初の記述子は listen 用記述子のままであり、accept() はそのソケットをクローズするまで何度でも呼び出せる。
遠隔のホストと通信を行う。send()とrecv()、またはwrite()とread()を使用する。
不要になったら、close() を使ってオープンされた各ソケットをクローズする。なお、fork() が行われた場合、各プロセスは見えているソケットを全てクローズしなければならず、複数のプロセスが同じソケットを同時に使ってはならない。
C99 でのサーバー側のソースコード。
TCPクライアントの設定は、以下のように行われる。
TCPソケットを生成する(socket()呼び出し)
connect() でサーバに接続する。このとき、sockaddr_in 構造体の sin_family フィールドは AF_INET か AF_INET6 とし、sin_port には通信相手が listen しているはずのポート番号をネットワークバイトオーダで設定し、sin_addr にもネットワークバイトオーダで相手の(IPv4 か IPv6 の)アドレスを設定する。
サーバと通信する。send()とrecv()、またはwrite()とread()を使用する。
コネクションの終了と削除処理を close() で行う。なお、fork() が行われた場合、各プロセスは見えているソケットを全てクローズしなければならず、複数のプロセスが同じソケットを同時に使ってはならない。
C99 でのクライアント側のソースコード。
上記のソースコードは gcc の場合 -std=c99 をつけることによりコンパイル可能であるが、-std=gnu99 を使用した場合は最初から定義されているので #define _BSD_SOURCE はあっても無くてもどちらでも良い。#define _BSD_SOURCE が無いと herror() が使えない。