kazmax - Linux で自宅サーバー

send - システムコールの説明 - Linux コマンド集 一覧表

  1. 名前
  2. 書式
  3. 説明
  4. 返り値
  5. エラー
  6. 準拠
  7. 注意
  8. バグ
  9. 関連項目

名前

send, sendto, sendmsg - ソケットへメッセージを送る

書式

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int s , const void * buf , size_t len , int flags );
ssize_t sendto(int s , const void * buf , size_t len , int flags , const struct sockaddr * to , socklen_t tolen );
ssize_t sendmsg(int s , const struct msghdr * msg , int flags );

説明

システムコール send (), sendto (), sendmsg ()は、もう一方のソケットへメッセージを転送するのに使用される。

send ()は、ソケットが "接続された (connected)" 状態にある場合にのみ使用できる (つまり、どの相手に送信するかは既知である)。 send ()と write ()の違いは、引き数に flags があるかどうかだけである。 引き数 flags が 0 の場合、 send ()は write ()と等価である。 また、 send( s , buf , len , flags )は sendto( s , buf , len , flags ,NULL,0)と等価である。

引き数 s は、データを送信するパケットのファイル・ディスクリプタである。

sendto ()は、接続型 (connection-mode) のソケット (SOCK_STREAM, SOCK_SEQPACKET) で 使用された場合、引き数 totolen は無視される (各々の引き数が NULL と 0 でない場合は EISCONN エラーも返される)。 また、ソケットが実際には接続されていなかった時には ENOTCONN エラーが返される。 接続型のソケット以外で使用された場合は、接続先のアドレスは to で与えられ、そのサイズは tolen で指定される。 sendmsg ()では、接続先のアドレスは msg.msg_name で与えられ、そのサイズは msg.msg_namelen で指定される。

send ()と sendto ()では、メッセージは buf に格納されており、その長さは len であると解釈される。 sendmsg ()では、メッセージは 配列 msg.msg_iov の各要素が指す位置に格納されている。 sendmsg ()では、補助データ (制御情報とも呼ばれる) を送信することもできる。

メッセージ長が長過ぎるために、そのソケットが使用するプロトコルでは、 メッセージをソケットに渡されたままの形で送信することができない場合、 EMSGSIZE エラーが返され、そのメッセージは転送されない。

send ()では、配送の失敗の通知は明示的に行われる。 ローカル側でエラーが検出された場合は、返り値 -1 として通知される。

メッセージがソケットの送信バッファに入れることができない場合、 send ()は通常は停止 (block) する (ソケットが非停止 (non-blocking) I/O モード でない場合)。非停止モードの場合には EAGAIN を返す。いつデータをさらに送信できるようになるかを知るために、   select (2) コールを使用することができる。

flags パラメータは、以下のフラグの (0 個以上の) ビット単位の論理和を とったものを指定する。

MSG_CONFIRM (Linux 2.3 以降のみ)
転送処理に進展があった、つまり相手側から成功の応答を受けたことをリンク層に 知らせる。リンク層がこの通知を受け取らなかった場合には、通常どおり (ユニキャスト ARP を使うなどの方法で) 近傍 (neighbour) の再検索を行う。 SOCK_DGRAMSOCK_RAW のソケットに対してのみ有効で、現在のところ IPv4 と IPv6 のみ実装されている。 詳しくは   arp (7) 参照のこと。
MSG_DONTROUTE
パケットを送り出すのにゲートウェイを使用せず、 直接接続されているネットワーク上のホストだけに送る。 通常、このフラグは診断 (diagnostic) やルーティング・プログラムに よってのみ使用される。このフラグは、経路制御が行われるプロトコルファミリー に対してのみ定義されている。パケットソケットには定義されていない。
MSG_DONTWAIT
非停止 (non-blocking) 操作を有効にする。操作が停止されるような場合には EAGAIN を返すようにする ( fcntl (2)の F_SETFLO_NONBLOCK を指定することによっても有効にできる)。
MSG_EOR
レコードの終了を指示する ( SOCK_SEQPACKET のようにこの概念に対応しているソケット種別のときに有効)。
MSG_MORE (Linux 2.4.4 以降)
呼び出し元にさらに送るデータがあることを示す。 このフラグは TCP ソケットとともに使用され、 TCP_CORK ソケットオプションと同じ効果が得られる ( tcp (7)を参照)。 TCP_CORK との違いは、このフラグを使うと呼び出し単位で この機能を有効にできる点である。 Linux 2.6 以降では、このフラグは UDP ソケットでもサポートされており、 このフラグ付きで送信された全てのデータを一つのデータグラムにまとめて 送信することを、カーネルに知らせる。まとめられたデータグラムは、 このフラグを指定せずにこのシステムコールが実行された際に初めて送信される ( udp (7)に記載されているソケットオプション UDP_CORK も参照)。
MSG_NOSIGNAL
ストリーム指向のソケットで相手側が接続を切断した時に、エラーとして SIGPIPE を送信しないように要求する。この場合でも EPIPE は返される。
MSG_OOB
"帯域外 (out-of-band)" データをサポートするソケット (例えば SOCK_STREAM )で 帯域外 データを送る。下位プロトコルも 帯域外 データをサポートしている必要がある。

msghdr 構造体の内容は以下の通り。 各フィールドの正確な記述については   recv (2) と以下の説明を参照すること。


struct msghdr { void *msg_name; /* 追加のアドレス */ socklen_t msg_namelen; /* アドレスのサイズ */ struct iovec *msg_iov; /* scatter/gather 配列 */ size_t msg_iovlen; /* msg_iov の要素数 */ void *msg_control; /* 補助データ(後述) */ socklen_t msg_controllen; /* 補助データバッファ長 */ int msg_flags; /* 受信メッセージのフラグ */ };

msg_controlmsg_controllen メンバーを使用して制御情報を送信することができる。 カーネルが処理できる制御バッファのソケットあたりの最大長は、 sysctl パラメータの net.core.optmem_max の値に制限されている。   socket (7) を参照。

返り値

成功した場合、これらのシステムコールは送信されたバイト数を返す。 エラーの場合、 -1 を返し、 errno を適切に設定にする。

エラー

これらはソケット層で発生する一般的なエラーである。これ以外に、下層の プロトコル・モジュールで生成されたエラーが返されるかもしれない。 これらについては、それぞれのマニュアルを参照すること。

EACCES
(Unix ドメインソケットはパス名で識別される。) ソケット・ファイルへの書き込み許可がなかったか、パス名へ 到達するまでのディレクトリのいずれかに対する検索許可がなかった。 ( path_resolution (2)も参照のこと)
EAGAIN または EWOULDBLOCK
ソケットが非停止に設定されており、 要求された操作が停止した。
EBADF
無効なディスクリプターが指定された。
ECONNRESET
接続が接続相手によりリセットされた。
EDESTADDRREQ
ソケットが接続型 (connection-mode) ではなく、 かつ送信先のアドレスが設定されていない。
EFAULT
ユーザー空間として不正なアドレスがパラメーターとして指定された。
EINTR
データが送信される前に、シグナルが発生した。
EINVAL
不正な引き数が渡された。
EISCONN
接続型ソケットの接続がすでに確立していたが、受信者が指定されていた。 (現在のところ、この状況では、このエラーが返されるか、 受信者の指定が無視されるか、のいずれかとなる)
EMSGSIZE
そのソケット種別 ではソケットに渡されたままの形でメッセージを送信する必要があるが、 メッセージが大き過ぎるため送信することができない。
ENOBUFS
ネットワーク・インターフェースの出力キューが一杯である。 一般的には、一時的な輻輳 (congestion) のためにインターフェースが 送信を止めていることを意味する。 (通常、Linux ではこのようなことは起こらない。デバイスのキューが オーバーフローした場合にはパケットは黙って捨てられる)
ENOMEM
メモリが足りない。
ENOTCONN
ソケットが接続されておらず、接続先も指定されていない。
ENOTSOCK
引き数 s がソケットでない。
EOPNOTSUPP
引き数 flags のいくつかのビットが、そのソケット種別では不適切なものである。
EPIPE
接続指向のソケットでローカル側が閉じられている。 この場合、 MSG_NOSIGNAL が設定されていなければ、プロセスには SIGPIPE も同時に送られる。

準拠

4.4BSD, SVr4, POSIX.1-2001. (これらの関数コールは 4.2BSD で最初に登場した)。
POSIX.1-2001 には、 MSG_OOBMSG_EOR フラグだけが記載されている。 MSG_CONFIRM フラグは Linux での拡張である。

注意

上記のプロトタイプは Single Unix Specification に従っている。 glibc2 も同様である。 flags 引き数は 4.x BSD では int であり、libc4 と libc5 では unsigned int である。 len 引き数は 4.x BSD と libc4 では int であり、libc5 では `size_t' である。 tolen 引き数は 4.x BSD と libc4 と libc5 では `int' である。   accept (2) も参照すること。
POSIX.1-2001 では、構造体 msghdr のフィールド msg_controllensocklen_t 型であるべきだとされているが、 現在の glibc (glibc 2.4) では size_t 型である。

バグ

Linux は ENOTCONN を返す状況で EPIPE を返すことがある。

関連項目