用户端在使用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. sql server lower函数

    lower()函数 --将大写字符数据转换为小写字符数据 语法:lower(character_expression) --character_expression是指定要进行转换的字符串

  2. L2Dwidget.js L2D网页动画人物添加

    hexo 添加live2d看板动画 https://www.jianshu.com/p/3a6342e16e57 首先贴出官网代码 官网地址配置:https://www.npmjs.com/packa ...

  3. java实现spark常用算子之frist

    import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...

  4. vsCode 前端插件推荐-和插件配置

    参考自网站:https://segmentfault.com/a/1190000011779959 插件安装完成之后,还要对一些插件进行配置,例如: vetur默认配置, 配置的过程: 打开 文件 & ...

  5. js介绍及语法结构

    javaScript它是一门动态的,弱类型的,解释型面向Web的编程语言.虽然名字里有Java但其它与Java无关.它可以用来增强页面动态效果,实现页面与用户之间的实时,动态交互. javascrip ...

  6. @babel/traverse 使用方法小记

    @babel/traverse 官网: https://babeljs.io/docs/en/babel-traverse github:https://github.com/babel/babel/ ...

  7. JavaScript学习基础

    基本语法    JavaScript语法和Java语言类似,每个语句以 : 结束,语句块用 {...}包起来.JavaScript并不强制要求在每个语句的结尾加: ,但是建议都加上,不给自己找麻烦.  ...

  8. 多线程编程-- part5 锁的种类以及辨析

    java中的锁,可以分为同步锁和JUC包中的锁. 同步锁 通过synchronized关键字进行同步,实现对竞争资源的互斥访问的锁,. 原理:对于每一个对象,有且只有一个同步锁,在同一时间点,所有的线 ...

  9. zookeeper+activemq高可用集群搭建

    一.准备工作: 准备三台机器:192.168.35.111192.168.35.112192.168.35.113 二.搭建zookeeper 三台机器上均要搭建zookeeper服务// 下载zoo ...

  10. 关于Vue-$router传参出现刷新页面或者返回页面丢失数据的问题

    也算是踩到坑了,但不是我踩到的,不过还是得说下这个问题,很严重,对于小白和初学者是比较有帮助的,如果使用到路由传参,请选择你想要的传参方式params或者query 1.query this.$rou ...