5.7 send() と recv()---話せよ、ベイビー!
この2つの関数は、ストリームソケットまたは接続されたデータグラムソケットで通信を行うためのものです。通常の非接続型データグラムソケットを使いたい場合は、以下の sendto() と recvfrom() の章を参照する必要があります。
send() の書式。
int send(int sockfd, const void *msg, int len, int flags);
sockfd はデータを送信したいソケット記述子(socket() で返されたものでも accept() で取得したものでも可)、msg は送信したいデータへのポインタ、len はそのデータの長さ(バイト数)です。flags を 0 に設定するだけです(フラグに関する詳しい情報は send() の man ページを参照してください)。
サンプルコードとしては、以下のようなものがあります。
char *msg = "Beej was here!";
int len, bytes_sent;
.
.
.
len = strlen(msg);
bytes_sent = send(sockfd, msg, len, 0);
.
.
.
send() は実際に送信されたバイト数を返しますが、これは送信するように指示した数よりも少ないかもしれません!つまり、大量のデータを送信するように指示しても、それが処理しきれないことがあるのです。その場合、できる限りのデータを送信し、残りは後で送信するように指示します。send() が返す値が len の値と一致しない場合、残りの文字列を送信するかどうかはあなた次第だということを覚えておいてください。良いニュースはこれです。パケットが小さければ(1K以下とか)、おそらく全部を一度に送信することができるでしょう。ここでも、エラー時には -1 が返され、 errno にはエラー番号がセットされます。
recv() の書式は、多くの点で類似しています。
int recv(int sockfd, void *buf, int len, int flags);
sockfd は読み込むソケット記述子、buf は情報を読み込むバッファ、len はバッファの最大長、flags は再び 0 に設定できます(フラグについては recv() の man ページを参照してください)。
recv() は、実際にバッファに読み込まれたバイト数を返し、エラーの場合は -1 を返します(それに応じて errno が設定されます)。
待ってください!recv() は 0 を返すことがあります。これは、リモート側が接続を切断したことを意味します!0 という返り値は、recv() がこのような事態が発生したことをあなたに知らせるためのものです。
ほら、簡単だったでしょう?これでストリームソケットでデータのやり取りができるようになったぞ。やったー!あなたは Unix ネットワークプログラマーです!