前言

    sendmsg和recvmsg函数是一对相对下层的套接字发送、接受函数。

通过这对函数,我们能够设置或者取得数据包的一些额外的控制信息。这些信息中比較经常使用的就是本文要介绍的发送、接受接口信息。通过这对函数,我们能够指定一个数据包发送的时候使用的接口(网卡)或者获得一个接受到数据包的来源接口。

sendmsg函数使用

sendmsg(fd, &mhdr, 0)函数中最重要的就是msghdr结构体。其定义例如以下:
struct msghdr {
void *msg_name; #发送地址
socklen_t msg_namelen; #前者长度
struct iovec *msg_iov;#发送数据缓冲区的指针
size_t msg_iovlen;#发送数据长度
void *msg_control; #控制数据指针
size_t msg_controllen;#控制数据长度
int msg_flags;
};

在我们发送一个数据包之前。要首先把要发送的数据以及相关控制信息填写到这个结构体中。

    这个结构体中包括的是数据以及控制信息的指针。因此在发送之前我们还须要另外为数据和控制信息分配空间。

数据就不用说了,直接char buf[MAX_MSG_SIZE]就可以。难点在于控制信息。

首先要定义一个msghdr 结构体。这个结构体用来存储全部的控制信息和发送的数据包:

struct msghdr mhdr;

    接着定义控制信息结构体cmsghdr :

struct cmsghdr *cmsg;

    我们要首先通过CMSG_SPACE 宏计算出控制信息cmsghdr结构体所需的空间大小。接着为控制信息结构体指针分配内存。cmsghdr的大小跟你要填写的控制消息有关。我们这里要填写的是发送接口控制信息,这个控制信息还须要一个结构体struct
in6_pktinfo结构体来承载,所以这里cmsghdr的大小则跟in6_pktinfo的大小有关:

struct in6_pktinfo pk;//定义接口控制数据结构
pk.ini_index=1;//指定接口(这里的1是接口索引號)
cmsglen = CMSG_SPACE (sizeof(pk));//计算cmsghdr结构在mhdr中所需的大小
mhdr.msg_control=(void *)malloc(cmsglen);//为cmsghdr分配内存,并在mhdr中填写控制信息的指针
mhdr.msg_controllen=cmsglen;
cmsg = CMSG_FIRSTHDR (&mhdr);//我们利用CMSG_FIRSTHDR找到控制信息在mhdr结构体中的真正地址
//利用CMSG_LEN算出控制信息cmsghdr结构中真正的控制数据的长度
cmsg->cmsg_len = CMSG_LEN(sizeof(*pk));
cmsg->cmsg_level = IPPROTO_IPV6;//填写cmsghdr控制信息结构体
cmsg->cmsg_type = IPV6_PKTINFO;
//CMSG_DATA(cmsg) 能够找到真正的控制信息在cmsghdr结构体中的位置,之后我们就能够利用memcpy把控制结构体的数据复制到cmsg中:
memcpy(CMSG_DATA(cmsg), pk, sizeof(*pk));
以上是发送的过程。接收过程跟发送过程类似。

最好需要注意的是。要发送以及接收这些控制信息,我们必需要设置套接字选项:
int val = 1;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
&val, sizeof(val)) < 0)
return -1;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVDSTOPTS,
&val, sizeof(val)) < 0)
return -1;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDR,
&val, sizeof(val)) < 0)
return -1;

利用sendmsg和recvmsg来指定发送接口或者获取接收数据接口的更多相关文章

  1. 猫眼电影App抓包获取评论数据接口

     之前在CSDN程序人生公众号上看到了这篇文章<邪不压正>评分持续走低,上万条网友评论揭秘,是救救姜文还是救救观众?,文中提到了通过抓包猫眼App发现了评论的数据接口:http://m.m ...

  2. ASP.NET API(MVC) 对APP接口(Json格式)接收数据与返回数据的统一管理

    话不多说,直接进入主题. 需求:基于Http请求接收Json格式数据,返回Json格式的数据. 整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性 ...

  3. java URL实现调用其他系统发送报文并获取返回数据

    模拟本系统通过Url方式发送报文到目标服务器,并获取返回数据:(实现类) import java.io.BufferedOutputStream; import java.io.BufferedRea ...

  4. Android Studio利用异步任务AsyncTask发送post请求获取json数据

    syncTask,是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主 ...

  5. 用javascript向一个网页连接接口发送请求,并接收该接口返回的json串

    一般前端与后端的互交都是通过json字符串来互交的,我的理解就是与网页接口的来回数据传递采用的数据结构就是json.一般是这样. 比如后端的代码是这样的: @RequestMapping(value ...

  6. java接收数据接口

    1.数据接收接口: 这个可以考虑最简单的Servlet方法,而且效率较高: import java.io.PrintWriter;import java.text.SimpleDateFormat;i ...

  7. C#中两个List<TModel>中根据指定条件--判断并获取不同数据的数据集合2

    方式一:Linq List<Test> list = new List<Test>(); list.Add(new Test { score = 10, name = &quo ...

  8. C#数据路接口中获取SQL数据的用法

    获取一条记录 string sql = string.Format(“”); DataRow row; if (GetFirstDataRow(sql, out row))      {        ...

  9. postman发送数据,django 获取接收数据

    postman发起请求如下图 在django中使用如下方式获取token print(request.META) token = request.META.get('HTTP_X_TOKEN')

随机推荐

  1. QNX 多线程 (线程1每隔20ms读取 number;线程2每隔10ms计算一次)

    #include <pthread.h>#include <stdio.h>#include <sys/time.h>#include <string.h&g ...

  2. 与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器

    原文:与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器 [索引页][源码下载] 与众不同 windows phone (18) - Device ...

  3. 【Demo 0009】表视图控制器

    本章学习要点:       1.  掌握表视图控制器结构;       2.  掌握表视图控制器的基本使用;       3.  掌握表视图表格的基本使用:       4.  掌握自定义表视图表格及 ...

  4. 自己定义UITabBarController

    网上大多的自己定义TabBar都是继承View的,项目中要用到path+Tabbat这种话(path用的MMDrawerController这个框架),继承View的Tabbar是无法满足条件的(不是 ...

  5. 在SharePoint 2010中部署RBS (转)

    一.RBS(Remote BLOB Storage)简单介绍 在SharePoint的大部分企业应用案例中,SharePoint都是要承担着非常繁重的文件管理工作,这些文件类型包含了Word文档,Ex ...

  6. MySQL中同一时候存在创建和上次更新时间戳字段解决方法浅析

    在写这篇文章之前.明白我的MySQL版本号. mysql> SELECT VERSION(); +------------+ | VERSION() | +------------+ | 5.5 ...

  7. 网络编程API-上 (基本API)

    htons.ntohs.htonl和ntohl函数 Linux提供了4个函数来完毕主机字节序和网络字节序之间的转换 #include <netinet/in.h> uint16_t hto ...

  8. Go的String转码包

    https://github.com/qiniu/iconv https://github.com/djimenez/iconv-go 这是与go不相干的转码包:https://github.com/ ...

  9. poj 3270 更换使用

    1.确定初始和目标状态. 明确.目标状态的排序状态. 2.得出置换群,.比如,数字是8 4 5 3 2 7,目标状态是2 3 4 5 7 8.能写为两个循环:(8 2 7)(4 3 5). 3.观察当 ...

  10. hdu 1024(dp)

    传送门:Max Sum Plus Plus 题意:从n个数中选出m段不相交的连续子段,求这个和最大. 分析:经典dp,dp[i][j][0]表示不取第i个数且前i个数分成j段达到的最优值,dp[i][ ...