はじめに
こんにちは。
42tokyoといったところで、コンピュータサイエンス?を学んでいます。
最近、簡単なIRCサーバを実装する課題を通して、ソケットプログラミングについて学びました。
本記事は、ソケットの作成についてまとめています。
間違い等があれば、ご指摘ください。
本記事では、TCP/IP上で行われる通信を想定しています。
本記事における用語について
「ソケットAPI」とは、
- ソケットに関連するシステムコールの総称
- ソケットに関連するシステムコールとは、socket()、bind()、listen()、connect()、accept()、send()、recv()など
「ソケット構造体」とは、
- 本記事において、あるソケット(TCP)に関する諸情報をまとめて「ソケット構造体」と呼ぶ
- 諸情報とは、以下の通り
- FIFOバッファ(SendQ, RecvQ)
- ソケットの状態
- ローカルipアドレス
- ローカルポート
- リモートipアドレス
- リモートポート
- 「ソケット構造体」は、socket()によって生成されたディスクリプタでアクセスする
- 「ソケットAPI」は「ソケット構造体」が持つデータを扱うものと言える
まとめ(全体図)
参考
サーバ=クライアント間における接続処理について
サーバ側の動き(socket(); -> bind(); -> listen();まで)
int socket(int domain, int type, int protocol);
- ソケット構造体が作成される
- 戻り値のディスクリプタは、この構造体にアクセスできる
- ソケットの状態は、Closed
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- クライアントが識別可能なローカルポートを設定する
- クライアントは、ここで設定されたローカルポートを目印に、connect()を実行する
int listen(int sockfd, int backlog);
- クライアントのconnect()を待ち受ける状態になる
- ソケットの状態が、Listeningになる
クライアント側の動き(socket(); -> connect();まで)
int socket(int domain, int type, int protocol);
- ソケット構造体が作成される
- 戻り値のディスクリプタは、この構造体にアクセスできる
- ソケットの状態は、Closed
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- ソケット構造体の4箇所にそれぞれ値が代入される
- ローカルポートには、使用されていない値が割り振られる(bind()していないので)
- サーバとの接続処理が始まり完了すると、ソケットの状態は、Establishedとなる
- ソケットの状態が、Cnnectedになる
サーバ側の動き(accept()まで)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- クライアントから接続要求がきたら、新しいソケット構造体を作成する
- 各フィールドには、パケットから適切な値を取り出し代入する
- ローカルipアドレス = パケットの送信先ipアドレス
- ローカルポート = パケットの送信先ポート(サーバのローカルポートと同じ値)
- リモートipアドレス = パケットの送信元ipアドレス
- リモートポート = パケットの送信元ポート
- ソケットの状態は、Connecting、not-quite-connected socketsの順番に遷移し、クライアントとの接続処理が完了すると、Establishedとなる
さいごに
聞き慣れない用語が沢山あったので、理解に時間が掛かりました。
不備があればお申し付けください。
次回は、recv();, send();について学んだことをまとめていきます。
ありがとうございました。
つづき