zoukankan      html  css  js  c++  java
  • 套接字之msghdr结构

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

     1 /* 用户空间的消息头 */
     2 struct user_msghdr {
     3     /* 指向地址结构 */
     4     void        __user *msg_name;    /* ptr to socket address structure */
     5     /* 地址结构长度 */
     6     int        msg_namelen;        /* size of socket address structure */
     7     /* 数据 */
     8     struct iovec    __user *msg_iov;    /* scatter/gather array */
     9     /* 数据区个数 */
    10     __kernel_size_t    msg_iovlen;        /* # elements in msg_iov */
    11     /* 控制信息 */
    12     void        __user *msg_control;    /* ancillary data */
    13     /* 控制信息缓冲区长度 */
    14     __kernel_size_t    msg_controllen;        /* ancillary data buffer length */
    15 
    16     /* 接收信息的标志 */
    17     unsigned int    msg_flags;        /* flags on received message */
    18 };

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

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

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

     1 struct iov_iter {
     2     int type; /* 类型,读写方向,以及数据指针类型ITER_XXX */
     3     size_t iov_offset; /* 偏移 */
     4     size_t count; /* 数据总字节数 */
     5     union {
     6         /* 数据向量指针 */
     7         const struct iovec *iov;
     8         const struct kvec *kvec;
     9         const struct bio_vec *bvec;
    10         struct pipe_inode_info *pipe;
    11     };
    12     union {
    13         /* 向量中的数据块数量 */
    14         unsigned long nr_segs;
    15         struct {
    16             int idx;
    17             int start_idx;
    18         };
    19     };
    20 };

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

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

    总的数据组织结构如下:

     1 struct msghdr{
     2     iov_iter {
     3         type
     4         iov_offset
     5         count   | total_buff_len = buff0_len + buff1_len + buff2_len ?
     6         ---------
     7         iov_base|------>[buff0]
     8         iov_len | buff0_len
     9         ---------
    10         iov_base|------>[buff1]
    11         iov_len | buff1_len
    12         ---------
    13         iov_base|------>[buff2]
    14         iov_len | buff2_len
    15         ---------
    16         nr_segs | iov_count = 3
    17        
    18     }
    19  }
  • 相关阅读:
    C/C++字符串函数之复制函数
    tesseract api C++使用例子
    error C2275: “XXX”: 将此类型用作表达式非法
    Socket通信原理探讨(C++为例)
    模拟按键,点击,滑动,在光标处输出字符
    安卓使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)
    【 转】__try,__except,__finally,__leave异常模型机制
    提高VS2010运行速度的技巧
    解决VS2010子目录中的.cpp文件引用上一级目录的stdafx.h找不到定义的问题
    1009MySQL数据库InnoDB存储引擎Log漫游
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11749287.html
Copyright © 2011-2022 走看看