SEND(2) | Linux Programmer's Manual | SEND(2) |
send, sendto, sendmsg - ソケットへメッセージを送る
#include <sys/types.h> #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
システムコール send(), sendto(), sendmsg() は、もう一方のソケットへメッセージを転送するのに使用される。
send() は、ソケットが 接続された (connected) 状態にある場合にのみ使用できる (つまり、どの相手に送信するかは既知である)。 send() と write(2) の違いは、引き数に flags があるかどうかだけである。 引き数 flags にフラグが指定されない場合、 send() は write(2) と等価である。 また、
send(sockfd, buf, len, flags);
は以下と等価である。
sendto(sockfd, buf, len, flags, NULL, 0);
引き数 sockfd は、データを送信するパケットのファイルディスクリプターである。
sendto() は、接続型 (connection-mode) のソケット (SOCK_STREAM, SOCK_SEQPACKET) で 使用された場合、引き数 dest_addr と addrlen は無視される (各々の引き数が NULL と 0 でない場合は EISCONN エラーも返される)。 また、ソケットが実際には接続されていなかった時には ENOTCONN エラーが返される。 接続型のソケット以外で使用された場合は、接続先のアドレスは dest_addr で与えられ、そのサイズは addrlen で指定される。 sendmsg() では、接続先のアドレスは msg.msg_name で与えられ、そのサイズは msg.msg_namelen で指定される。
send() と sendto() では、メッセージは buf に格納されており、その長さは len であると解釈される。 sendmsg() では、メッセージは 配列 msg.msg_iov の各要素が指す位置に格納されている。 sendmsg() では、補助データ (制御情報とも呼ばれる) を送信することもできる。
メッセージ長が長過ぎるために、そのソケットが使用するプロトコルでは、 メッセージをソケットに渡されたままの形で送信することができない場合、 EMSGSIZE エラーが返され、そのメッセージは転送されない。
send() では、配送の失敗の通知は明示的に行われる。 ローカル側でエラーが検出された場合は、返り値 -1 として通知される。
メッセージがソケットの送信バッファーに入れることができない場合、 send() は通常は停止 (block) する (ソケットが非停止 (nonblocking) I/O モード でない場合)。非停止モードの場合にはエラー EAGAIN か EWOULDBLOCK で失敗する。 いつデータをさらに送信できるようになるかを知るために、 select(2) コールを使用することができる。
flags 引き数は、以下のフラグの (0 個以上の) ビット単位の論理和を とったものを指定する。
Linux 2.6 以降では、このフラグは UDP ソケットでもサポートされており、 このフラグ付きで送信された全てのデータを一つのデータグラムにまとめて 送信することを、カーネルに知らせる。まとめられたデータグラムは、 このフラグを指定せずにこのシステムコールが実行された際に初めて送信される (udp(7) に記載されているソケットオプション UDP_CORK も参照)。
sendmsg()
で利用されている
msghdr
構造体は以下の通り。
struct msghdr {
void *msg_name; /* 追加のアドレス */
socklen_t msg_namelen; /* アドレスのサイズ */
struct iovec *msg_iov; /* scatter/gather 配列 */
size_t msg_iovlen; /* msg_iov の要素数 */
void *msg_control; /* 補助データ (後述) */
size_t msg_controllen; /* 補助データバッファー長 */
int msg_flags; /* フラグ (未使用) */ };
フィールド msg_name は、 未接続のソケットでデータグラムの宛先アドレスを指定するのに使用される。 このフィールドはアドレスを格納したバッファーを指す。 フィールド msg_namelen にはアドレスの大きさを設定しなければならない。 接続済のソケットについては、これらのフィールドにはそれぞれ NULL と 0 を指定しなければならない。
フィールド msg_iov と msg_iovlen は scatter-gather 用の場所を指定する。 writev(2) と同じ。
フィールド msg_control と msg_controllen を使用して制御情報を送信することができる。 カーネルが処理できる制御バッファーのソケットあたりの最大長は、 /proc/sys/net/core/optmem_max の値に制限されている。 socket(7) を参照。
フィールド msg_flags は無視される。
成功した場合、これらのシステムコールは送信されたバイト数を返す。 エラーの場合、 -1 を返し、 errno を適切に設定にする。
これらはソケット層で発生する一般的なエラーである。これ以外に、下層の プロトコルモジュールで生成されたエラーが返されるかもしれない。 これらについては、それぞれのマニュアルを参照すること。
ソケットファイルへの書き込み許可がなかったか、パス名へ到達するまでの ディレクトリのいずれかに対する検索許可がなかった。 (path_resolution(7) も参照のこと)
(UDP ソケットの場合) ユニキャストアドレスであるかのように、 ネットワークアドレスやブロードキャストアドレスへの送信が試みられた。
4.4BSD, SVr4, POSIX.1-2001. (これらの関数コールは 4.2BSD で最初に登場した)。
POSIX.1-2001 には、 MSG_OOB と MSG_EOR フラグだけが記載されている。 POSIX.1-2008 では MSG_NOSIGNAL が規格に追加されている。 MSG_CONFIRM フラグは Linux での拡張である。
POSIX.1-2001 では、構造体 msghdr のフィールド msg_controllen は socklen_t 型であるべきだとされているが、 現在の glibc では size_t 型である。
sendmmsg(2) には、一度の呼び出しでの複数のデータグラムの送信に使用できる Linux 固有の システムコールに関する情報が書かれている。
Linux は ENOTCONN を返す状況で EPIPE を返すことがある。
sendto() の利用例が getaddrinfo(3) に記載されている。
fcntl(2), getsockopt(2), recv(2), select(2), sendfile(2), sendmmsg(2), shutdown(2), socket(2), write(2), cmsg(3), ip(7), socket(7), tcp(7), udp(7)
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2014-08-19 | Linux |