SENDMMSG - Linux手册页

时间:2019-08-20 17:59:19  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-06-09

名称

sendmmsg-在套接字上发送多个消息

语法

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <sys/socket.h>

int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
             int flags);

说明

sendmmsg()系统调用是sendmsg(2)的扩展,它允许调用方使用单个系统调用在套接字上传输多个消息。 (这对于某些应用程序具有性能优势。)

sockfd参数是要在其上传输数据的套接字的文件描述符。

msgvec参数是指向mmsghdr结构数组的指针。该数组的大小在vlen中指定。

mmsghdr结构定义为:

struct mmsghdr {
    struct msghdr msg_hdr;  /* Message header */
    unsigned int  msg_len;  /* Number of bytes transmitted */
};

msg_hdr字段是msghdr结构,如sendmsg(2)中所述。 msg_len字段用于返回msg_hdr中消息发送的字节数(即,与单个sendmsg(2)调用的返回值相同)。

flags参数包含在一起进行或运算的标志。这些标志与sendmsg(2)相同。

一个阻塞的sendmmsg()调用将阻塞,直到发送了vlen消息为止。无阻塞呼叫将发送尽可能多的消息(达到vlen指定的限制)并立即返回。

sendmmsg()返回时,msgvec连续元素的msg_len字段将更新为包含从相应的msg_hdr发送的字节数。调用的返回值指示已更新的msgvec元素的数量。

返回值

成功时,sendmmsg()返回从msgvec发送的消息数;如果此值小于vlen,则调用方可以再次尝试使用sendmmsg()调用来发送其余消息。

如果出错,则返回-1,并且将errno设置为指示错误。

错误说明

错误与sendmsg(2)相同。仅当无法发送数据报时才返回错误。另请参阅错误。

版本

在Linux 3.0中添加了sendmmsg()系统调用。 glibc中的支持已在2.14版中添加。

遵循规范

sendmmsg()是特定于Linux的。

备注

vlen中指定的值以UIO_MAXIOV(1024)为上限。

BUGS

如果在至少发送一条消息后发生错误,则调用成功,并返回发送的消息数。错误代码丢失。呼叫者可以从第一个失败的消息开始重试传输,但是不能保证如果返回错误,它将与前一次呼叫丢失的错误相同。

示例

下面的示例使用sendmmsg()通过一个系统调用在两个不同的UDP数据报中发送onetwo和3。第一个数据报的内容源自一对缓冲区。

#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);

    exit(0);
}

另外参见

recvmmsg(2),sendmsg(2),socket(2),socket(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/