一、再谈端口号
在 TCP / IP 协议中,用 "源 IP", "源端口号", "目的 IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信(可以通过 netstat -n 查看)
我们需要端口号到进程的唯一性,所以一个进程可以绑定多个端口号,但是一个端口号不能绑定多个进程。
二、UDP协议格式
如何分离报头和有效载荷?
用定长报头,找到报文长度和报文起始位置。
如何将有效载荷分用?
找到目的 port 查哈希表找进程
UDP 的特点
无连接 : 知道对端的 IP 和端口号就直接进行传输 , 不需要建立连接。
不可靠: 没有确认机制, 没有重传机制 ; 如果因为网络故障该段无法发到对方 , UDP 协议层也不会给应用层返回任何错误信息 ; 面向数据报。
不能够灵活的控制读写数据的次数和数量。
面向数据报
应用层交给 UDP 多长的报文 , UDP 原样发送 , 既不会拆分 , 也不会合并。
如果发送端调用一次 sendto, 发送 100 个字节 , 那么接收端也必须调用对应的一次 recvfrom, 接收 100 个字节 ; 而不能循环调用 10 次 recvfrom, 每次接收 10 个字节。
UDP 的缓冲区
UDP 没有真正意义上的 发送缓冲区 . 调用 sendto 会直接交给内核 , 由内核将数
据传给网络层协议进行后续的传输动作 ;
UDP 具有接收缓冲区 . 但是这个接收缓冲区不能保证收到的 UDP 报的顺序和
发送 UDP 报的顺序一致 ; 如果缓冲区满了 , 再到达的 UDP 数据就会被丢弃 ;
UDP 的 socket 既能读 , 也能写 , 这个概念叫做 全双工
三、Linux中报文管理
在同一时间会有大量的报文在操作系统里面,要先描述再组织,所以一定会有标识报文字段的结构体 struct sk_buff
最后用 struct sk_buff* next 来连接所有报文结构体,形成链表管理。