/* /usr/include/netdb.h */
struct servent
{
char *s_name; /* Official service name. */
char **s_aliases; /* Alias list. */
int s_port; /* Port number. */
char *s_proto; /* Protocol to use. */
};
s_name: サービス名.
s_aliases: 別名リスト.
s_port: ポート番号.
s_proto: 利用できるプロトコル名("TCP", "UDP").
・sockaddr_inをmemsetで初期化.
・アドレスファミリとアドレスを設定
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
INADDR_ANYはホストのもつ全てのIPアドレス.
htonl関数はホストのバイトオーダをネットワークのバイトオーダ(long型で)に変換する関数.
htonl: host to network long
・ポート番号を設定
ポート番号は文字列で与えられる.
・数字だった場合
addr.sin_port = htons(atoi(portnum));
htons: host to network short
・サービス名だった場合("http"とか)
struct servent *se =
getservbyname(portnum, "tcp");
addr.sin_port = se->port;
getservbyname関数はサービス名からポート番号を調べ,servent構造体を返す関数.
サービス名とポート番号の対応は/etc/services
2,ソケットの作成
socket(int domain, int type, int protocol);
第一引数: アドレスファミリ
第二引数: プロトコルのタイプ(TCP->SOCK_STREAM, UDP->SOCK_DGRAM)
第三引数: プロトコル.プロトコルファミリが1つのプロトコルのみを
サポートする場合は0を指定できる.
返り値: ディスクリプタ
int soc = socket(addr.sin_family, SOCK_STREAM, 0);
3,ソケットオプションの指定
int setsockopt(int socfd, int level, int optname, const void *optval, socklen_t optlen);
第一引数: ソケットのディスクリプタ.
第二引数: オプションの層.ソケット層でオプションを指定するときはSOL_SOCKET.
第三引数: 設定するオプションの名前.
第四引数: オプションに設定する値.
第五引数: 設定する値のサイズ.
・再利用フラグをONにする
int opt = 1;
setsockopt(soc, SOL_SOCKET,
SO_REUSEADDR, &opt, sizeof(opt));
再利用フラグがOFFでbindした場合,通信が中断したりすると同じアドレスとポートで再びbindができなくなる.
4,バインド
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
第一引数: ソケットのディスクリプタ.
第二引数: アドレス構造体.
第三引数: アドレス構造体のサイズ.
・ソケットとアドレスをバインドする.
第二引数は(struct sockaddr *)にキャストする.
bind(soc,
struct sockaddr *) &addr, sizeof(addr));
//
5,listen
int listen(int sockfd, int backlog);
第一引数: ソケットのディスクリプタ.
第二引数: 保留中の接続のキューの最大長.
・接続待ちソケットにする.
listen(soc, SOMAXCONN);