#define _GNU_SOURCE /* feature_test_macros(7) 参照 */ #include <sys/socket.h> int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags);
sockfd 引数は、 データを送信するソケットのファイルディスクリプターである。
msgvec 引数は mmsghdr 構造体の配列である。 この配列の大きさは vlen で指定する。
mmsghdr 構造体は <sys/socket.h> で次のように定義されている。
struct mmsghdr {
struct msghdr msg_hdr; /* メッセージヘッダー */
unsigned int msg_len; /* 送信されたバイト数 */
};
msg_hdr フィールドは、 sendmsg(2) で説明されている msghdr 構造体である。 msg_len フィールドは msg_hdr から送信されたメッセージのバイト数を返すのに使用される。 この値は sendmsg(2) をこのヘッダーに対して呼び出した場合の返り値と同じである。
flags 引数には複数のフラグを論理和 (OR) で指定できる。フラグは sendmsg(2) と同じである。
停止 (blocking) モードの sendmmsg() の呼び出しは、 vlen 個のメッセージが送信されるまで停止する。 非停止 (nonblocking) モードの呼び出しでは、 送信できるだけのメッセージ (最大で vlen 個) を送信し、 すぐに返る。
sendmmsg() が返った際には、 msgvec の送信が行われた要素の msg_len フィールドは、対応する msg_hdr から送信されたバイト数が入っている。 呼び出しの返り値は、更新された msgvec の要素数である。
エラーの場合、 -1 を返し、 errno にエラーを示す値を設定する。
#define _GNU_SOURCE #include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h>
int
main(void)
{
int sockfd;
struct sockaddr_in addr;
struct mmsghdr msg[2];
struct iovec msg1[2], msg2;
int retval;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket()");
exit(EXIT_FAILURE);
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(1234);
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
perror("connect()");
exit(EXIT_FAILURE);
}
memset(msg1, 0, sizeof(msg1));
msg1[0].iov_base = "one";
msg1[0].iov_len = 3;
msg1[1].iov_base = "two";
msg1[1].iov_len = 3;
memset(&msg2, 0, sizeof(msg2));
msg2.iov_base = "three";
msg2.iov_len = 5;
memset(msg, 0, sizeof(msg));
msg[0].msg_hdr.msg_iov = msg1;
msg[0].msg_hdr.msg_iovlen = 2;
msg[1].msg_hdr.msg_iov = &msg2;
msg[1].msg_hdr.msg_iovlen = 1;
retval = sendmmsg(sockfd, msg, 2, 0);
if (retval == -1)
perror("sendmmsg()");
else
printf("%d messages sent\n", retval);