用户端在使用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. ionic 提示 Error: Could not find gradle wrapper within Android SDK.

    Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK. 到And ...

  2. docker之常用命令

    1) docker run -p : --name mysql -v d:/docker/mysql/conf:/etc/mysql/conf.d -v d:/docker/mysql/logs:/l ...

  3. Linux下nouveau操作和GPU的操作,nouveau拯救

    之前也提到了,旧机器上有一块NVIDIA的显卡,装了ubuntu16.04后一直没有安装驱动.这周算是有点时间,就差点作了死. 首先必须澄清,这个不是正确的安装过程,起码我就报了memory erro ...

  4. 韦东山嵌入式Linux学习笔记04--点亮开发板的一个LED灯

    搜索开发板原理图LED的走线           LED8是网线接口的指示灯. 在这里我们尝试用汇编代码控制D10, 也就是LED1,它连接到EINT4/GPF4,读取芯片手册 有原理图可知,如果需要 ...

  5. poj 1458 Common Subsequence(dp)

    Common Subsequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 46630   Accepted: 19 ...

  6. 文件I/O简述

    什么是I/O 宏观上讲,I/O是信息处理系统(例如计算机)与外部世界(可能是人或其他信息处理系统)之间的通信.输入(Input)是系统接收的信号或数据,输出(Output)是从其发送的信号或数据.另一 ...

  7. Linux中FTP服务器配置

         1.FTP服务器的一些基本概念       (1)FTP连接方式     控制连接:标准端口为21,用于发送FTP命令信息.     数据连接:标准端口为20,用于上传.下载数据.      ...

  8. idea使用问题总结

    一.创建Spring 的配置文件需要加入一个pom.xml 的依赖 <dependency> <groupId>org.springframework</groupId& ...

  9. PAT Basic 1019 数字黑洞 (20 分)

    给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字.一直重复这样做,我们很快会停在有“数字黑洞 ...

  10. Detecting Unstable Periodic Orbits in Chaotic Experimental Data (解析)

    原文链接:https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.76.4705 发表在:PRL 1996 ---------------- ...