用户端在使用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. Python 东方财富网-股市行情数据抓取

    东方财富网 股市行情数据抓取: http://quote.eastmoney.com/center/gridlist.html#hs_a_board 请求数据未入库处理,其中数据只存入数据文本,未做存 ...

  2. 08 Json结构化Datetime时间以及保留中文

    错误描述: import json import datetime a = datetime.datetime.now() print(a) b = json.dumps(a) print(b) 如上 ...

  3. 访问接口错误,com.netflix.client.ClientException: Load balancer does not have available server for client: panfeng-item-service

    com.netflix.client.ClientException: Load balancer does not have available server for client: panfeng ...

  4. linux命令详解——vim

    显示行号:命令模式下set nu 定位到指定行: 命令模式下,:n   比如想到第2行,:2 编辑模式下,ngg  比如想到第5行 5gg(或者5G) 打开文件定位到指定行   vim  +n  te ...

  5. tornada-模板

    tornado模板 1.配置模板路径 (project/config.py) # coding=utf-8 import os BASE_DIRS = os.path.dirname(__file__ ...

  6. cmd窗口颜色设置

    color  02    第一个数字是背景颜色,第二个是文字颜色.

  7. VMware的linux虚拟机配置ip后无法ping通宿主机

    VMware的linux虚拟机配置ip(使用eth0)后无法ping通宿主机,同样宿主机无法ping通linux虚拟机. 可能原因:linux虚拟机使用的网卡,与本机使用的网卡不同,配置成与本机一致的 ...

  8. 标准C语言(10)

    指针数组的每个存储区是一个指针类型的存储区,字符指针数组包含多个字符类型的指针,每个字符类型指针可以代表一个字符串.字符指针数组可以用来代表多个相关字符串,二维字符数组也可以用来记录多个相关字符串,通 ...

  9. xss过滤方法

    用的白名单过滤,是我们的论坛自用的方法,也许考虑不周,欢迎来黑我们的论坛!https://www.ebcms.com/forum.html // 安全过滤 function safe_html($ht ...

  10. Android 热修复(一)

    名词: dex:java文件编译class 然后生成 dex文件在Android上运行: 1.dex分包: 2.找出出现问题的dex文件进行替换操作 3.下载dex文件,静默替换有问题的dex文件,进 ...