ソケットの作成
ソケットとは?
ソケットとは、ユーザにとってのデータの出入り口です。 ユーザはソケットに対してデータを書き込んだり読み込んだりするだけで通信が行えます。
ソケットは、2つ以上のソケットが互いに関係を持つことではじめて有効になります。 糸電話の紙コップ部分は、両端の紙コップを糸で繋いではじめて利用可能になります。 ソケットも紙コップと同じで、通信相手のソケットと仮想的な関係を持ってはじめて利用可能になります。 (ただし、通信方式によって関係の持ち方や関係を持つ相手の数などが異なります。)
お互い関係を持ったソケットでは、片方に書き込んだデータがもう片方のソケットから出て行きます。 そのため、ユーザはソケットの裏側で動いている複雑な通信プロトコルを意識せずに通信を行えます。
Linuxでのソケット作成
Linuxでは、socket()関数を利用してソケットを作成できます。 以下にsocket()関数を使ったソケット作成例を示します。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int
main()
{
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("socket failed\n");
return 1;
}
return 0;
}
Linuxでは、ソケットは「int」で表現されるファイルディスクリプタです。 ファイルをopenしたときに出来るファイルディスクリプタと同様にソケットもファイルディスクリプタです。 全ての通信は、socket()が返すファイルディスクリプタを使って行われます。 socket()は、失敗すると-1を返します。
注意しなくてはならないのは、0が正常な値であることです。 例えば、0番でopenされているファイルディスクリプタが無い状態でsocketシステムコールを利用した場合にはsocketは0を返します。
socket()関数は3つの引数を取ります。 通信路で使われるプロトコルは、アドレスファミリ、ソケットタイプ、プロトコルの3つの組み合わせにより決定します。 一つ目の引数がアドレスファミリ、二つ目の引数がソケットタイプを表します。 三つ目の引数はプロトコルを表します。 ここでは、とりあえずAF_INET(IPv4)とSOCK_STREAM(TCP)という組み合わせでソケットを作成していますが、詳細は後述します。
上記例ではTCPのソケットを作成しています。 TCPとUDPでは、ソケットを作った後の処理が大きく異なります。 TCPやUDPを使ったソケット通信の詳細は、後に行いたいと思います。