一、再谈端口号
在 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 来连接所有报文结构体,形成链表管理。