网络初阶——运输层:TCP 协议(Part2)
一、文件与 socket 的关系
所以从上图可以看出,文件描述符是可以通过多个箭头来访问 socket 和报文的。 而且,其中 struct udp_socket 和 struct tcp_socket 相当于继承了基类 struct socket ,同时 struct proto_ops 和 file_operations 表面上看只是存函数指针的,但其实就是 C 语言版的多态。
二、 再谈报文
1、如何管理报文
1.1. 报文的描述
tail:报文有效载荷部分中已存数据的结尾。
end:报文有效载荷部分的结尾。
head:报文的开头。
data: 报文已存数据的开头。
1.2. 报文的组织( struct sk_buff_head )
2、如何给报文加减报头
由网络基础可知,应用层的数据是由上到下不断加报头,然后到数据链路层再发送的。而当我们知道报文是上面那样的数据结构时,操作系统怎么给报文加报头呢?其实操作系统会在 char 数组开始处再开一段空间,来存放该层的报文,然后再把 head 指针和 data 指针都往上移,就完成了。所以,其实报文的封装和解包本质上只要移动 head 和 data 指针就可以了。
但是你或许会问:既然报文的数据结构是双链表节点,且 TCP 一发就把整个报文发了,那么 TCP 又是怎么按字节流发送呢?其实下图数据部分只增不减只是一种情况。当 http 报文传到运输层时,TCP 就会先算好一个 TCP 报文的有效载荷的大小,如果有效载荷比 http 报文大,那么这个 http 报文就不会被分成多个 TCP 报文节点;但如果有效载荷比这个 http 报文小,那么这个 http 报文节点就会被分成多个 TCP 报文节点;然后 TCP 会给每个报文节点编号。