sendmsg() - ソケットに関するメッセージの送信

標準

標準/拡張機能 C/C++ 依存項目

XPG4.2
Single UNIX Specification、バージョン 3

両方  

形式

X/Open:
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>

ssize_t sendmsg(int socket, struct msghdr *msg, int flags);
バークレー・ソケット:
#define _OE_SOCKETS
#include <sys/socket.h>

int sendmsg(int socket, struct msghdr *msg, int flags);

機能説明

sendmsg() 関数は、メッセージ・ヘッダーの配列で渡されたソケット記述子を持つソケット上でメッセージを送信します。
パラメーター
説明
socket
ソケット記述子。
msg
メッセージがそこから送信されるメッセージ・ヘッダーの配列。
flags
次のフラグの 1 つ以上を指定します。複数のフラグを指定する場合は、論理 OR 演算子 (|) を使用してフラグを分離する必要があります。
MSG_OOB
ソケット上のアウト・オブ・バンドのデータを送信します。アウト・オブ・バンドのデータをサポートするのは、SOCK_STREAM ソケットのみです。アウト・オブ・バンドのデータは、単一バイトです。

アウト・オブ・バンドのデータが、2 つのプログラム間で送信される前に、いくらか調整を図る必要があります。データをインライン で読み取るつもりではない場合には、アウト・オブ・バンドのデータの受信側 は、アウト・オブ・バンドのデータの送信時に生成される SIGURG シグナル の受信側を指定する必要があります。受信側が設定されていないと、シグナルは送信されません。受信側を設定するには、fcntl() 関数の action パラメーターを F_SETOWN に設定し、PID または GID のいずれかを指定します。アウト・オブ・バンド・データの受信側の設定について詳しくは、fcntl() - オープン・ファイル記述子の制御を参照してください。

データの受信側は、setsockopt() 関数を使用した SO_OOBINLINE ソケット・オプションの設定により、アウト・オブ・バンドのデータをインラインで受け取るかどうかを判別します。アウト・オブ・バンドのデータの受信の詳細は、setsockopt() - ソケットに関連したオプションの設定recv() - ソケット上のデータの受信recvfrom() - ソケット上のメッセージの受信、および recvmsg() - ソケット上のメッセージの受信およびメッセージ・ヘッダーの配列への保管 を参照してください。

MSG_DONTROUTE
この操作の間、SO_DONTROUTE ソケット・オプションはオンになっています。このフラグは通常、診断プログラムまたはルーティング・プログラムによって使用されます。
メッセージ・ヘッダーは msghdr 構造体で定義 され、これは sys/socket.h ヘッダー・ファイル で見つけることができ、以下のエレメントが含まれています。
エレメント
説明
msg_iov
メッセージが中に入っている iovec バッファーの配列。
msg_iovlen
msg_iov 配列内のエレメントの数。
msg_name
受信側のアドレスが入っているバッファーへのオプション・ポインター。
msg_namelen
アドレス・バッファーのサイズ。
caddr_t msg_accrights
送信または受信されるアクセス権 (ユーザーによって指定された場合は無視されます)。このフィールドは、z/OS®UNIX サービスによって無視されます。
int msg_accrightslen
アクセス権データの長さ (ユーザーにより指定された場合は無視されます)。このフィールドは、z/OSUNIX サービスによって無視されます。
msg_control
補助データ。
msg_controllen
補助データ・バッファー長。
msg_flags
受信メッセージのフラグ。

対のシーケンスで構成される補助データです。それぞれ、データ配列とその後ろに続く cmsghdr 構造体から構成されます。データ配列には補助データ・メッセージが入り、cmsghdr 構造体には アプリケーションが正しくデータを解析できるようにする記述情報が入ります。

sys/socket.h ヘッダー・ファイルは、少なくとも以下のエレメントを 含んでいる cmsghdr 構造体を定義します。
エレメント
説明
cmsg_len
ヘッダーを含むデータ・バイト・カウント。
cmsg_level
送信元のプロトコル。
cmsg_type
プロトコル固有のタイプ。
以下の補助データが、IPv4 レベルで使用可能です。
補助データ
説明
IP_PKTINFO
(RAW および UDP) パケットの送信に使用されるインターフェース、およびパケット・ソース IP として使用される IP アドレスを指定します。 データは、netinet/in.h に定義された in_pktinfo 構造体で渡されます。
以下の補助データが、IPv6 レベルで使用可能です。
補助データ
説明
IPV6_HOPLIMIT
(RAW、TCP、および UDP) 発信パケットの最大ホップ限界を指定します。データは、netinet/in.h に定義された構造体で渡されます。
IPV6_PATHMTU
(RAW および UDP) 接続されたソケットの宛先に対するパス MTU 値を指定します。データは、netinet/in.h に定義された構造体で渡されます。
IPV6_PKTINFO
(RAW および UDP) パケットの送信に使用されるインターフェース、およびパケット・ソース IP として使用される IP アドレスを指定します。 データは、netinet/in.h に定義された in6_pktinfo 構造体で渡されます。
以下の補助データが、ソケット・レベルで使用可能です。
補助データ
説明
SCM_RIGHTS
送信または受信されるアクセス権を含むデータ配列を指定します。この補助データが有効なのは、AF_UNIX ドメインの場合のみです。データは、sys/socket.h に定義された構造体で渡されます。
sys/socket.h ヘッダー・ファイルは、次のマクロを定義して、メッセージ・ヘッダーと関連した補助データのデータ配列へのアクセス権を 取得します。
CMSG_DATA(cmsg)
引数が cmsghdr 構造体へのポインターである場合には、このマクロは、cmsghdr 構造体と関連したデータ配列への 符号なしの文字ポインターを戻します。
CMSG_NXTHDR(mhdr,cmsg)
最初の引数が msghdr 構造体へのポインターであり、2 番目の引数が補助データの cmsghdr 構造体へのポインターである (その msghdr 構造体の msg_control フィールドによって指し示されている) 場合、このマクロは次の cmsghdr 構造体へのポインターを戻します。この構造体が補助データの最後の cmsghdr 構造体である場合は、NULL ポインターを戻します。
CMSG_FIRSTHDR(mhdr)
引数が msghdr 構造体へのポインターである場合には、このマクロは、この msghdr 構造体と関連した補助データの 最初の cmsghdr 構造体へのポインターを戻します。あるいは msghdr 構造体と関連した補助データがない場合には、NULL ポインターを戻します。

sendmsg() 呼び出しは、接続状態であるかどうかにかかわらず、ソケットに適用されます。

この呼び出しは、送信データの長さを戻します。送信するソケット・データを保留するのに使用可能な バッファー・スペースが十分でなく、ソケットがブロック・モードに なっている場合には、sendmsg() は追加の バッファー・スペースが使用可能になるまで呼び出し元をブロック します。ソケットが非ブロック・モードの場合には、sendmsg() は -1 を戻し、エラー・コードを EWOULDBLOCK に設定します。非ブロッキング・モードの設定方法の説明については、fcntl() - オープン・ファイル記述子の制御または ioctl() - 装置の制御を参照してください。

データグラム・ソケットの場合、データグラムが TCP/IP バッファーに適合すれば、この呼び出しはデータグラム全体を送信します。ストリーム・ソケットは、データを分離する境界のない情報ストリームのように動作します。例えば、アプリケーションで 1000 バイトを送信したい場合には、この関数へのそれぞれの呼び出しによって、1 バイト、または 10 バイト、あるいは 1000 バイト全体が送信できます。したがって、ストリーム・ソケットを使用するアプリケーションは、この呼び出しを ループに入れて、すべてのデータが送信されてしまうまで、この関数を呼び出す 必要があります。

IPv6 用ソケット・アドレス構造体: AF_INET6 ソケットでは、msg_name が指定された場合、アドレスは sockaddr_in6 アドレス構造体にある必要があります。sockaddr_in6 構造体は、ヘッダー・ファイル netinet/in.h の中に 定義されます。

C++ の特殊な動作: C++ でこの関数を使用するには、_XOPEN_SOURCE_EXTENDED 1 フィーチャー・テスト・マクロを 使用する必要があります。

注: sendmsg() 関数は、拡張 ASCII の拡張機能のレベルに依存します。詳細は、拡張 ASCII サポートを参照してください。

戻り値

正常に実行された場合は、sendmsg() は、メッセージの長さ (バイト単位) を戻します。

0 またはそれより大きい値は、送信されたバイト数を示していますが、これはデータの送達が完了したことを保証するわけではありません。データの送達が完了していない場合は、ピア・ソケットおよびあとで生成された SIGPIPE シグナルを使って接続を終了することができます。

正常に実行されなかった場合、sendmsg() は -1 を戻して、errno を次のいずれかの 値に設定します。
エラー・コード
説明
EADDRNOTAVAIL
ipi6_addr は、ipi6_ifindex インターフェース上では利用不能です。
EAFNOSUPPORT
アドレス・ファミリーはサポートされていません (それは AF_UNIX、AF_INET、または AF_INET6 ではありません)。
EBADF
socket が無効ソケット記述子です。
ECONNREFUSED
接続する試みはリジェクトされました。
ECONNRESET
接続はピアによって強制的にクローズされました。
EFAULT
msg を使用すると、呼び出し元のアドレス・スペースの外側のストレージへの アクセスを試みるようになります。
EHOSTUNREACH
ifi6_index が指定するインターフェースを介した宛先出口への経路は存在しません。
EINTR
データが送信される前に、シグナルが sendmsg() に割り込みました。
EINVAL
msg_namelength が、指定アドレス・ファミリーの有効アドレスのサイズではありません。
EIO
ネットワークまたはトランスポートで障害が発生しました。
EMSGSIZE
メッセージが大きすぎて、1 つのデータグラムとして送信されませんでした。デフォルトは、large-envelope-size です。(エンベロープが使用され、TCP/IP 処理中にデータグラムおよびフラグメントが 保持されます。2 KB より大きい UDP データグラムは、出力用に処理されている間、および入力でアプリケーション・プログラムによって受信されるのを待っている間、ラージ・エンベロープにより保持されます。)
ENETDOWN
ipi6_ifindex が指定したインターフェースは、IPv6 の使用は可能ではありません。
ENOBUFS
メッセージの送信にバッファー・スペースを使用することができません。
ENOTCONN
ソケットが接続していません。
ENOTSOCK
記述子はファイル用であり、ソケット用ではありません。
ENXIO
ipi6_ifindex に指定されたインターフェースは存在しません。
EOPNOTSUPP
flags で設定されている値 (1 つ以上) をサポートしていない socket 引数がソケットと関連付けられています。
EPIPE
接続されたストリーム・ソケットの場合には、ピア・ソケット との接続が失われています。SIGPIPE シグナルが呼び出しプロセスに送信されます。
EWOULDBLOCK
socket は非ブロック・モードであり、使用可能なデータ・バッファーがないか、バッファーが使用可能になる前に SO_SNDTIMEO タイムアウト値に達しました。
以下は、AF_UNIX 専用です。
エラー・コード
説明
EACCES
パス接頭部のコンポーネントに対する検索許可が拒否されているか、あるいは名前付きソケットへの書き込みアクセスが拒否されています。
EIO
ファイル・システムの読み取り中または書き込み中に、入出力エラーが発生しました。
ELOOP
ソケット・アドレスでのパス名の変換で見つかったシンボリック・リンクが 多すぎます。
ENAMETOOLONG
パス名のコンポーネントが NAME_MAX 文字を超えたか、あるいはパス名全体が PATH_MAX 文字を超えました。
ENOENT
パス名のコンポーネントに既存のファイル名が指定されていないか、またはパス名が空ストリングです。
ENOTDIR
ソケット・アドレスのパス名のパス接頭部のコンポーネントが、ディレクトリーでは ありません。

関連情報