函数原型

       #include <sys/types.h>
#include <sys/socket.h>
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

两函数都用到struct msghdr:

           struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};

msg_name  and  msg_namelen  specify the source address if the socket is unconnected; msg_name may be given as a NULL pointer if no names are desired or required.

The fields msg_iov and msg_iovlen  describe  scatter-gather  locations,  as  discussed  in  readv(2).

The field msg_control, which has length msg_controllen, points to a buffer for other protocol control-related messages or miscellaneous ancillary data.  When recvmsg()  is  called,  msg_controllen should  contain the length of the available buffer in msg_control; upon return from a successful call it will contain the length of the control message sequence.

The msg_flags field in the msghdr is set on return of recvmsg(), MSG_EOR, MSG_TRUNC, MSG_CTRUNC, MSG_OOB, MSG_ERRQUEUE.

消息的格式定义为struct cmsghdr:

           struct cmsghdr {
socklen_t cmsg_len; /* data byte count, including hdr */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
/* followed by
unsigned char cmsg_data[]; */
};

控制消息的访问通过宏cmsg(3)实现:

       #include <sys/socket.h>

       struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);

These  macros  are used to create and access control messages (also called ancillary data) that are not a part of the socket payload.

Ancillary data is a sequence of struct cmsghdr structures with appended data.  This sequence should be accessed using only the macros described in this manual page and never directly.

创建消息:

To create ancillary data, first initialize the msg_controllen member of the msghdr with the  length  of  the  control message buffer.

Use CMSG_FIRSTHDR() on the msghdr to get the first control message and CMSG_NXTHDR() to get all sub‐sequent ones.

In each control message, initialize cmsg_len (with CMSG_LEN()), the other cmsghdr header  fields,  and the  data portion using CMSG_DATA().

Finally, the msg_controllen field of the msghdr should be set to the sum of the CMSG_SPACE() of the length of all control  messages  in  the  buffer.

示例

       This code looks for the IP_TTL option in a received ancillary buffer:

           struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
int received_ttl; /* Receive auxiliary data in msgh */
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
if (cmsg->cmsg_level == IPPROTO_IP
&& cmsg->cmsg_type == IP_TTL) {
ttlptr = (int *) CMSG_DATA(cmsg);
received_ttl = *ttlptr;
break;
}
}
if (cmsg == NULL) {
/*
* Error: IP_TTL not enabled or small buffer
* or I/O error.
*/
}

The code below passes an array of file descriptors over a UNIX domain socket using SCM_RIGHTS:

           struct msghdr msg = {};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Contains the file descriptors to pass. */
char buf[CMSG_SPACE(sizeof myfds)]; /* ancillary data buffer */
int *fdptr; msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
/* Initialize the payload: */
fdptr = (int *) CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Sum of the length of all control messages in the buffer: */
msg.msg_controllen = cmsg->cmsg_len;

sendmsg/recvmsg和struct msghdr的更多相关文章

  1. UNIX网络编程——通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数

    在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符. 下面先来看两个函数: #include <sys/types.h> #in ...

  2. 通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数

    在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符. 下面先来看两个函数: #include <sys/types.h>  #i ...

  3. struct msghdr和struct cmsghdr【转载】

    理解struct msghdr当我第一次看到他时,他看上去似乎是一个需要创建的巨大的结构.但是不要怕.其结构定义如下:struct msghdr {    void         *msg_name ...

  4. 套接字I/O函数write/read writev/readv send/recv sendto/recvfrom sendmsg/recvmsg

    函数原型 read/write系原型 #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); #include ...

  5. 内核中用于数据接收的结构体struct msghdr(转)

    内核中用于数据接收的结构体struct msghdr(转) 我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,pin ...

  6. UNIX网络编程读书笔记:recvmsg和sendmsg函数

    这两个函数是最通用的I/O函数.实际上我们可以把所有read.readv.recv和recvfrom调用替换成recvmsg调用.类似地,各种输出函数调用也可以替换成sendmsg调用. #inclu ...

  7. 输入和输出(read,recv,recvmsg...和write,writev,writemsg)

    每一个TCP套接口有一个发送缓冲区,可以用SO_SNDBUF套接口选项来改变这个缓冲区的大小. 应用进程调用 write时,内核从应用进程的缓冲区中拷贝所有数据到套接口的发送缓冲区.如果套接口的发送缓 ...

  8. NetLink Communication Mechanism And Netlink Sourcecode Analysis

    catalog . Netlink简介 . Netlink Function API Howto . Generic Netlink HOWTO kernel API . RFC Linux Netl ...

  9. UNIX网络编程-基本API介绍(二)

    参考链接:http://www.cnblogs.com/riky/archive/2006/11/24/570713.aspx 1.getsockname和getpeername getsocknam ...

随机推荐

  1. WordPress 博客文章中google adsense广告展示方法之一

    http://log.medcl.net/item/2011/08/diving-into-elasticsearch-4-installation-and-configuration/ 看到这个网站 ...

  2. Atom 检测php错误扩展linter-php

  3. Linux命令-实时监测命令:watch

    watch 是一个非常实用的命令,基本所有的 Linux 发行版都带有这个小工具,如同名字一样,watch 可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行..在Linux下,watch是周期性 ...

  4. jsp地址栏传中文显示乱码解决方法

    格式一: 地址栏显示格式:http://localhost:8081/Jsp2/ahref2.jsp?id=32&name=%E7%8E%8B%E4%BA%91%E9%B9%8F 1.修改To ...

  5. OpenXml读取word内容注意事项

    OpenXml读取word内容注意事项 1.使用OpenXml读取word内容,word后缀必须是".docx":如果word后缀是".doc"需要转成&quo ...

  6. python学习笔记013——推导式

    1 推导式简介 推导式comprehensions(又称解析式),是Python的一种独有特性. 推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 推导式有三种形式: 1)列表推导式 (li ...

  7. Android 手机震动功能实现

    1首先在AndroidManifest.xml中添加震动权限 <uses-permission android:name="android.permission.VIBRATE&quo ...

  8. 如何生成KeyStore

    介绍如何生成keystore cmd下: 进入到jdk的bin目录,这样的话,android.keystore文件就会生成在这个目录下,签名的时候我们需要这个文件. C:\Program Files\ ...

  9. Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

    在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...

  10. 在Visual Studio中使用NuGet管理项目库

    NuGet是用来管理项目中引用的各个组件插件什么什么东西的东西,最近使用以后发现对于项目引用的维护非常方便. 暂时转一篇MSDN的文章,其实这个文章的内容就够了: http://msdn.micros ...