TCP/IP实现(一) 系统文件结构及mbuf

一.描述符

       在linux下编程时很多函数都会返回一个描述符,比如文件描述符,套接字描述符。那么描述符到底是什么呢?说到底描述符不过是一个数组下标,这个数组是由指向文件对象的指针组成的。文件对象是在文件被打开时创建的(这里的文件不仅仅是磁盘上的文件,也可以是套接字等),具体的关于文件对象的细节会在《linux内核解析——文件系统》相关博文中说明。

       现在只要知道:每个进程的进程描述符中都包含一个打开文件表,在linux下是struct files_struct结构,UNIX下是struct filedesc结构,每个打开文件表中右包含文件对象指针数组,即数组中每个元素指向struct file结构对象。每个文件对象中又包含操作文件的函数指针集,以及指向目录项节点(linux下的,在《linux内核解析——文件系统》博文中详述)的指针,或是指向一个socket对象。其结构图如下:

 

二.mbuf

        mbuf是一种缓存结构,用于在整个网络代码中存储各种信息,比如调用sendto发送的数据会从用户空间拷贝至mbuf中,mbuf的大小是固定的,每个mbuf总长为128字节,前20个字节为首部,mbuf分组的第一块mbuf还会用8个字节存储m_pkthdr.len(整个分组中数据的长度)和m_pkthdr.rcvif,,因此2个mbuf最多存储208个字节,当需要3个或3个以上的mbuf时会使用一种名为"簇"的大块缓存。

1.从mbuf看UDP的输出处理

         1)首先调用sendto函数发送数据,该函数将数据从用户空间拷贝到mbuf,假设数据为150字节,则此时mbuf链如下:

       2)接着到协议层需要在数据之前添加一个IP首部和一个TCP首部,为了·不移动数据部分,在链表之前又添加了一个mbuf用于存储协议首部,且为了便于低层写一添加自己的首部,如接口层添加以太网地址,而将UDP,IP首部放在新增mbuf的最下面。如图所示:

     3)接着到达接口层,将以太网地址添加到IP首部之前。

 

2.簇

    当mbuf中要存储的数据大于208字节时,即所需的mbuf数量达到3个及3个以上时,启用簇,此时会改变m_flag标志位,先对m_flag进行说明:1.m_flag为0,mbuf只包含数据;2.m_flag为M_PKTHDR,表明它是一个分组首部。(以上两种以在前面展示过了);3.m_flag为M_EXT,说明使用外部簇;4.m_flag为M_PKTHDR | M_EXT,说明使用外部簇且为分组首部

     所谓簇是一个大小为2048字节的内存块,当启用簇时m_data指向实际数据起始处,m_ext.ext_buf指向簇的首部,如下图所示:

       多个mbuf之间可以共享一个簇,这在TCP发送数据时十分有用,可避免为保留未确认数据而拷贝一个备份。由于TCP是一个可靠协议,因此必需维护一个已发送数据的副本,直到数据被对方确认。TCP/IP协议是这样做的:当发送数据时并不直接改变插口缓存中mbuf的m_data指针,而是复制mbuf的一个副本,改变副本中的m_data,并根据要发送的大小来添加首部分组,再将数据复制给网络设备(网卡)。当使用簇使,便不用复制数据,而只是复制了mbuf链,当收到数据确认后再改变插口缓存中mbuf的m_data指针。示意图如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值