• 套接字之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  }
  • 相关阅读:
    php字符串处理(邮件处理)
    phpstrtotime()对于31日求上个月有问题
    .net中linkbutton增加js验证
    excel 常用属性
    回车换行符总结
    视图增加自增id
    SQL优化索引、查询优化及分页算法方案
    js,cookies做悬浮购物车
    Server Application Unavailable出现的原因及解决方案集锦
    asp(javascript)中request.form("a").count 在ie6中总是为0
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11749287.html
Copyright © 2020-2023  润新知