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  }
  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11749287.html
Copyright © 2011-2022 走看看