用户端在使用sendmsg/recvmsg发送或者接收数据时,会使用msghdr来构造消息,其对应的内核结构为user_msghdr;其中msg_iov向量指向了多个数据区,msg_iovlen标识了数据区个数;在通过系统调用进入内核后,该结构中的信息会拷贝给内核的msghdr结构;

 /* 用户空间的消息头 */
struct user_msghdr {
/* 指向地址结构 */
void __user *msg_name; /* ptr to socket address structure */
/* 地址结构长度 */
int msg_namelen; /* size of socket address structure */
/* 数据 */
struct iovec __user *msg_iov; /* scatter/gather array */
/* 数据区个数 */
__kernel_size_t msg_iovlen; /* # elements in msg_iov */
/* 控制信息 */
void __user *msg_control; /* ancillary data */
/* 控制信息缓冲区长度 */
__kernel_size_t msg_controllen; /* ancillary data buffer length */ /* 接收信息的标志 */
unsigned int msg_flags; /* flags on received message */
};

在套接字发送接收系统调用流程中,send/recv,sendto/recvfrom,sendmsg/recvmsg最终都会使用内核中的msghdr来组织数据,如下,其中msg_iter为指向数据区域的向量汇总信息,其中数据区指针可能包含一个或者多个数据区,对于send/sendto其只包含了一个数据区;

 /*
* As we do 4.4BSD message passing we use a 4.4BSD message passing
* system, not 4.3. Thus msg_accrights(len) are now missing. They
* belong in an obscure libc emulation or the bin.
*/ struct msghdr {
/* 指向socket地址结构 */
void *msg_name; /* ptr to socket address structure */
/* 地址结构长度 */
int msg_namelen; /* size of socket address structure */
/* 数据 */
struct iov_iter msg_iter; /* data */
/* 控制信息 */
void *msg_control; /* ancillary data */
/* 控制信息缓冲区长度 */
__kernel_size_t msg_controllen; /* ancillary data buffer length */ /* 接收信息的标志 */
unsigned int msg_flags; /* flags on received message */ /* 异步请求控制块 */
struct kiocb *msg_iocb; /* ptr to iocb for async requests */
};

向量指向的数据通过iov_iter进行汇总信息和调整指向,其中iov为多个数据区的首地址,nr_segs为数据区个数;

 struct iov_iter {
int type; /* 类型,读写方向,以及数据指针类型ITER_XXX */
size_t iov_offset; /* 偏移 */
size_t count; /* 数据总字节数 */
union {
/* 数据向量指针 */
const struct iovec *iov;
const struct kvec *kvec;
const struct bio_vec *bvec;
struct pipe_inode_info *pipe;
};
union {
/* 向量中的数据块数量 */
unsigned long nr_segs;
struct {
int idx;
int start_idx;
};
};
};

对于每个数据区,iovec记录了数据区的首地址以及数据长度;

 /* 一个数据区的信息 */
struct iovec
{
/* 数据区地址 */
void __user *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */
/* 数据区长度 */
__kernel_size_t iov_len; /* Must be size_t (1003.1g) */
};

总的数据组织结构如下:

 struct msghdr{
iov_iter {
type
iov_offset
count | total_buff_len = buff0_len + buff1_len + buff2_len ?
---------
iov_base|------>[buff0]
iov_len | buff0_len
---------
iov_base|------>[buff1]
iov_len | buff1_len
---------
iov_base|------>[buff2]
iov_len | buff2_len
---------
nr_segs | iov_count = }
}

套接字之msghdr结构的更多相关文章

  1. Linux/UNIX套接字连接

    套接字连接 套接字是一种通信机子.凭借这样的机制.客户/server系统的开发工作既能够在本地单机上进行.也能够夸网络进行. 套接字的创建和使用与管道是有差别的.由于套接字明白地将客户和server区 ...

  2. 套接字socket 的地址族和类型、工作原理、创建过程

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

  3. apue学习笔记(第十六章 网络IPC:套接字)

    本章将考察不同计算机(通过网络连接)上的进程相互通信的机制:网络进程间通信. 套接字描述符 正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字. 许多处理文件描述符函数(如read和writ ...

  4. TCP套接字编程模型及实例

    摘要:     本文讲述了TCP套接字编程模块,包括服务器端的创建套接字.绑定.监听.接受.读/写.终止连接,客户端的创建套接字.连接.读/写.终止连接.先给出实例,进而结合代码分析. PS:本文权当 ...

  5. C++网络套接字编程TCP和UDP实例

    原文地址:C++网络套接字编程TCP和UDP实例作者:xiaojiangjiang 1.       创建一个简单的SOCKET编程流程如下 面向有连接的套接字编程 服务器: 1)  创建套接字(so ...

  6. 套接字I/O模型-完成端口IOCP

    “完成端口”模型是迄今为止最为复杂的一种I/O模型.然而,假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!但不幸的是,该模型只适用于Windows NT和W ...

  7. TCP套接字编程

    一.套接字(socket)函数 图1给出了在一个TCP客户与服务器通信的流程.服务器首先启动,稍后某个客户启动,它试图连接到服务器.假设客户给服务器发送一个请求,服务器处理该请求,并且给客户发回一个相 ...

  8. Linux学习笔记30——套接字

    一 什么是套接字 套接字是一种通信机制,凭借这种机制,客户/服务器系统的开发既可以在本地单机上进行,也可以跨网络进行. 二 套接字属性 套接字的特性由3个属性确定,它们是:域,类型和协议   1 套接 ...

  9. Win2 Socket(套接字)相关 API

    Socket(套接字) 作者信息 肖进 单位:南京中萃食品有限公司 资讯部 邮箱:xiaoj@njb.swirebev.com 电话:025-58642091 与socket有关的一些函数介绍 1.读 ...

随机推荐

  1. Select2的远程数据操作

    一.概述 如果下拉列表框中的内容太多,最好是使用Select2的远程数据进行筛选. 二.参考文献 https://select2.github.io/examples.html#data-ajax h ...

  2. 11 Mysql之配置双主热备+keeepalived.md

    准备 1. 双主 master1 192.168.199.49 master2 192.168.199.50 VIP 192.168.199.52 //虚拟IP 2.环境 master:nginx + ...

  3. CentOS查看Java进程并部署jar包

    查看Java进程获取pid号:ps -ef|grep java|grep -v grep 部署Javajar包并指定输出日志文件(null不输出):nohup java -jar xx.jar > ...

  4. Object.keys()返回对象自身可枚举属性组成的数组

    Object.keys()方法是对一个对象的key遍历,会把key组成一个数组返回 示例: // 参数为数组时,返回的是数组的索引 let arr1 = [1, 2, '3'] console.log ...

  5. IIS7发布asp.net mvc提示404

    之前服务器用的都是2003Server的服务器,发布mvc项目都没问题,今天换了一台机器,系统为Windows Server2008 R2  64位的发布mvc项目后就提示: 百度看到好多人说在web ...

  6. Delphi 无类型文件

  7. shelve:极其强大的序列化模块

    介绍 数据持久化,就是把数据从内存刷到磁盘上.但是要保证在读取的时候还能恢复到原来的状态.像pickle和json之类的持久化模块基本上无需介绍了,这里介绍两个其他很少用但是功能很强大的模块. dbm ...

  8. docker常用命令与容器创建

    ################docker安装##################### Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE. 社区版是免费提供给个 ...

  9. 关于tp5.0中对象数组转换普通数组使用助手函数collection而不是toArray

    tp5.0新版的模型查询返回默认对象,系统默认增加了toArray方法,许多开发者在all或select尝试使用toArray来转换为数组,在此希望开发者能理解对象的概念,尝试使用对象进行数据的使用, ...

  10. 【bzoj 4059】Non-boring sequences

    这题的重点不在于代码,而在于复杂度分析…… 首先我们肯定会写 $n^2$ 暴力,就是每次暴力扫 $[l,r]$ 区间,找到任意一个在此区间中只出现过一次的数.设其下标为 $mid$,显然在这个区间中任 ...