`
memorymyann
  • 浏览: 271966 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

20.辅助数据 和 传输描述字

阅读更多

打开一个文件或者一个套接口,如果想把这个已经打开的文件和套接口的描述字传给其他的进程(仅限于本机),可以通过发送unix域的辅助数据来完成。当然如果这2个进程是父子进程,则问题要简单很多,因为子进程继承了父进程打开的描述字。下面的问题是:如何在2个没有关系的进程之间传递描述字。

 

辅助数据又叫做控制信息,在之前介绍sendmsg和recvmsg中,对于数据结构struct msghd中有个字段void * msg_control;没有介绍。这就是辅助数据存储地方以及socklen_t msg_controllen;辅助数据的长度。基于字面意思也就是它可以用来传递一些比较特殊的信息。

 

辅助数据的结构:

struct  cmsghdr {

   socklen_t cmsg_len;

   int cmsg_level;

   int cmsg_type;

   /* followed by unsigned char cmsg_data[] */

}

 

如果是IPV4协议,则cmsg_level为IPPROTO_IP. cmsg_type值可以为:IP_RECVDSTADDR(接受UDP数据报的目的地址) 或者是IP_RECVIF (接受UDP数据报的接口索引)。

 

如果为IPV6协议,cmsg_level为IPPROTO_IPV6. cmsg_type值可以为:

IPV6_DSTOPTS(指定/接收目标选项)

IPV6_HOPLIMIT(指定/接收跳限)

IPV6_HOPOPTS(指定/接收步跳选项)

IPV6_NEXTHOP(指定下一跳地址)

IPV6_PKTINFO(指定/接收分组信息)

IPV6_RTHDR(指定/接收路由头部)

 

如果UNIX域协议,cmsg_level为SOL_SOCKET。cmsg_type值可以为:

SCM_RIGHTS(发送/接收描述字)

SCM_CREDS(发送/接收用户凭证)。

 

辅助数据有一个或者多个辅助数据对象组成,每个对象由cmsghdr开头,其后跟了数据,在cmsg_type和实际数据之间可能有填充字节,一个数据对象和下一个对象之间也可能有填充字节。之所以要有填充字节是为了使整个数据对象按照cmsg_type结构对齐。因此为了方便操作就定义了以下几种宏操作:

 

CMSG_FIRSTHDR(struct msghdr * msg);//返回第一个cmsghdr结构指针

CMSG_NXTHDR(struct msghdr * msg, struct cmsghdr * cmsgptr);//指向cmsgptr的下一个cmsghdr指针

CMSG_DATA(struct cmsghdr * cmsgptr);//指向cmsgptr相关联的数据的第一个字节指针

CMSG_LEN(unsigned int length); //给定数据量下,存储在cmsg_len中的位置

CMSG_SPACE(unsigned int length); //给定数据量下,一个辅助数据对象的大小

 

相对比较抽象,通过代码及注释来看下:

代码实现的是同机器上2个进程间通过unix域传递打开的文件描述字。

#include "/programe/net/head.h"
#include "sys/un.h"
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"

//打开监听套接字,等待从另一个进程传递过来打开的文件描述字信息
int main(int argc, char ** argv) {
        char buf[100];
        int sockfd;
        struct sockaddr_un addr;

        sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
        bzero(&addr, sizeof(addr));
        addr.sun_family = AF_LOCAL;
        strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path) - 1);
        unlink(argv[1]);
        int flag = bind(sockfd, (struct sockaddr *)&addr, SUN_LEN(&addr));//unix域,之前见过
        if(flag == -1) {
                printf("bind error\n");
                exit(1);
        }

        listen(sockfd, 10);

        int connfd = accept(sockfd, NULL, NULL);

        struct msghdr msg;
        struct iovec io;

        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        io.iov_base = buf;
        io.iov_len = 100;
        msg.msg_iov = &io;
        msg.msg_iovlen = 1; //msg普通数据的定义,在sendmsg与recvmsg里面见过.

        union {
                struct cmsghdr cmsg;
                char control[CMSG_SPACE(sizeof(int))];
        } control_un; //为了使整个数据结构对齐,所以定义了union对象,当然也可以使用malloc
        struct cmsghdr * cmptr;
        msg.msg_control = control_un.control;
        msg.msg_controllen = sizeof(control_un.control); //因为只有一个数据对象传送

        ssize_t size = recvmsg(connfd, &msg, 0);
        buf[size] = '\0';
        printf("get message:%s\n", buf);

        cmptr = CMSG_FIRSTHDR(&msg);//在接受到返回结果后,得到第一个控制信息对象
        if(!cmptr) {
                printf("some thing error!!!\n");
        } else {
                int recvfd = *((int *)CMSG_DATA(cmptr));//获取文件描述字信息
                char my[100];
                int length = read(recvfd, my, 100);
                my[length] = '\0';
                printf("%s\n", my);
                close(recvfd);
        }
        close(connfd);
        close(sockfd);
        exit(0);
}

 

 

#include "stdio.h"
#include "stdlib.h"
#include "/programe/net/head.h"
#include "string.h"
#include "sys/un.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
//打开一个文件,并将描述字传递给另一个进程
int main(int argc, char ** argv) {
        int sockfd;
        char buf[] = "hello world";
        int file = open("/programe/net/temp.txt", O_RDONLY);//打开文件,file就是即将要传输的描述字

        sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
        struct sockaddr_un addr;
        bzero(&addr, sizeof(addr));
        addr.sun_family = AF_LOCAL;
        strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path) - 1);

        connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un));

        struct msghdr msg;
        struct iovec io;

        union {
                struct cmsghdr cm;
                char control[CMSG_SPACE(sizeof(int))];
        } control_un; //同上

        struct cmsghdr * cmptr;
        msg.msg_control = control_un.control;
        msg.msg_controllen = sizeof(control_un.control);

        cmptr = CMSG_FIRSTHDR(&msg);
        cmptr->cmsg_len = CMSG_LEN(sizeof(int));
        cmptr->cmsg_level = SOL_SOCKET;
        cmptr->cmsg_type = SCM_RIGHTS;//说明要传递的是描述字

        *((int *)CMSG_DATA(cmptr)) = file;//将描述字放入传输对象中

        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        io.iov_base = buf;
        io.iov_len = sizeof(buf);
        msg.msg_iov = &io;
        msg.msg_iovlen = 1;

        ssize_t flag = sendmsg(sockfd, &msg, 0);
        printf("flag = %d\n", flag);
        close(sockfd);
        exit(0);

}

 

分享到:
评论

相关推荐

    数字海道测量数据传输标准(S-57)

    综上所述,S-57标准作为国际海道测量数据传输的核心规范之一,为电子海图的标准化和全球化应用奠定了坚实的基础。随着技术的进步和标准的不断优化,ECDIS将在未来的航海领域发挥更加重要的作用。

    佛山市道路运输车辆智能视频监控报警装置 - 数据传输格式说明.pdf

    总结来说,文档提供的内容详细描述了智能视频监控报警装置的数据传输格式,这些数据格式遵循特定的行业标准,并且在消息的通信和处理方面有着严格的规定和要求。这确保了数据传输的准确性和一致性,为智能视频监控...

    论文研究-异构数据库集成中数据传输问题的研究.pdf

    此外,文章还将探讨JavaMail在处理电子邮件服务中的应用,这虽然不是数据传输的核心部分,但可以提供一种辅助的数据传输手段。 在比较各种数据传输方法时,文章将着重分析它们在性能、可靠性、安全性和编程复杂性等...

    WH-T 32-2008 DMX512-A灯光控制数据传输协议

    《WH-T 32-2008 DMX512-A灯光控制数据传输协议》是中华人民共和国文化行业的一项重要标准,旨在规范灯光控制领域的数据传输,确保不同品牌和型号的灯光控制设备能够实现有效、稳定的互联互通。该标准基于美国国家...

    毕业设计WIFI共享、数据传输设计

    对于描述中的"基本功能已经完成",这可能意味着开发者已经实现了Wi-Fi热点的开启和关闭,以及简单的数据传输。然而,为了进一步完善,可以考虑以下几个方面: 1. **安全增强**:数据传输时应加密,防止中间人攻击,...

    .NET压缩传输数据集

    在.NET开发环境中,高效地处理和传输大数据集是常见的需求,特别是当数据量大到可能影响网络性能或消耗大量内存时。`.NET压缩传输数据集` 提供了解决这一问题的一种策略,它涉及到如何利用.NET框架中的类和库来压缩...

    行业分类-设备装置-对多媒体传输的辅助信息进行编码和解码的方法、装置和系统.zip

    随着互联网技术的快速发展,高效、高质量的多媒体数据传输成为了一个重要的研究课题。标题中的“行业分类-设备装置-对多媒体传输的辅助信息进行编码和解码的方法、装置和系统”揭示了这个主题的核心内容,即关注如何...

    usbtreeview.zip usb协议 usb描述符查看工具

    USB协议是计算机与外部设备之间进行数据传输的标准,它具有高速、低延迟、即插即用和热插拔的特点。USB协议定义了设备如何连接、通信以及如何供电。USB协议主要由以下几个核心部分组成: 1. **USB规范**:包括USB ...

    基于互联网的CAD_CAM工程数据文件传输.pdf

    OFTP广泛应用于欧洲企业的EDI数据传输。 随着互联网的快速发展,企业对基于Internet的网络传输协议的需求日益增长。因此,ODDETTE于2004年成立了OFTP2工作组,并于2007年成立了OFTP安全认证交换(SCX)项目组,于...

    行业分类-设备装置-基于云平台的CAD建模数据传输方法、服务器和客户端.zip

    设备装置-基于云平台的CAD建模数据传输方法、服务器和客户端”揭示了这个压缩包文件的主要内容,它涉及到CAD(计算机辅助设计)在云平台环境下的应用,特别是关于数据传输的方法,以及服务器和客户端的角色与交互。...

    全站仪数据传输串口调试助手

    总之,全站仪数据传输串口调试助手是工程技术人员进行测量工作的重要辅助工具,它简化了串口调试过程,优化了全站仪与计算机之间的数据交换,提升了工作效率和数据处理的准确性。对于需要处理大量测量数据的用户来说...

    qt udp传输文件

    4. **TCP辅助传输**:在描述中提到了TCP传输数据,TCP是一种面向连接、可靠的传输协议,适用于传输小量关键数据,比如文件头信息、确认信息等。可以创建`QTcpSocket`进行TCP通信,确保文件传输的相关控制信息的可靠...

    软件开发数据字典描述

    数据字典,简称DD,是系统设计中用来记录和描述系统中所有数据项、数据结构及其属性的一种文档。它是对数据流图(Data Flow Diagram, DFD)的有效补充,用于详尽地定义数据流图中的各个元素,包括数据流、数据存储、...

    hololens和电脑端的远程视频传输

    描述中提到的“hololens和电脑端的远程视频传输插件”,暗示了存在一种第三方软件插件或者开源项目,用于实现这种连接。用户可以在GitHub上搜索相关的项目,GitHub是一个全球知名的代码托管平台,拥有大量的开源项目...

    STM32F407通过USB驱动EC20.zip

    EC20是一款由 Quectel 制造的高性能、低功耗的4G LTE模块,它支持多种网络制式,如LTE-TDD/LTE-FDD/UMTS/GSM,可以实现高速数据传输和语音通信。 首先,要理解STM32F407的USB驱动机制。STM32F407集成了USB 2.0全速...

    DS18B20 串口打印,ds18b20输出数据的格式,C,C++

    描述中提到的“N76E003实现温度传感器DS18B20的串口打印”,意味着我们将使用N76E003单片机作为主控器来读取DS18B20的温度数据,并通过其内置的串口将这些数据发送到终端设备,如计算机,以便查看和记录。...

    辅助F340_CP200 UDP 传输的上位机软件

    标题中的“辅助F340_CP200 UDP 传输的上位机软件”表明这是一个专为F340和CP200设备设计的上位机程序,用于实现UDP(用户数据报协议)的数据传输功能。UDP是互联网协议栈中的一种传输层协议,它以无连接的方式工作,...

    TCP.rar_tcp_套接字通信

    4. **接受连接**:服务器调用accept函数接受客户端的连接请求,返回一个新的套接字描述符用于实际的数据传输。 5. **数据交换**:使用read和write函数读取和发送数据。由于TCP是流式协议,没有消息边界,所以通常...

    行业-电子政务-具有用于提供电力和交换数据的辅助电传动导管的焊接系统.zip

    在这个特定的案例中,我们关注的是一个焊接系统,它可能被用于建设或维护电子政务基础设施,尤其是那些涉及电力供应和数据传输的部分。 描述中提到的“具有用于提供电力和交换数据的辅助电传动导管的焊接系统”...

    zln数据集.zip zln数据集

    【描述】"zln数据集.zip" 是对这个压缩文件的简洁描述,没有提供具体的数据类型、格式或用途信息。不过,根据文件扩展名".zip"我们可以推断,这是一个使用ZIP格式压缩的文件,ZIP是一种常见的文件归档和压缩标准,它...

Global site tag (gtag.js) - Google Analytics