这次来分享一下我的TCP笔记吧,整理了一段时间
先来个补充知识
1 字节 = 8bit(我就是经常忘记的人)
为啥有IP
协议建立在IP层之上,需要IP层进行传输数据
这俩在什么层
运输层
TCP
特点
面向链接
点对点
可靠交付
全双工
面向字节流
TCP段格式
首部 160bit
源端口 16bit
目的端口 16bit
序号 数据部分在发送方数据流的位置 32bit
确认号 指出接收方希望收到对方下次发送的数据流中的位置 32bit 发送数据部分的第一个字节的序号(确认号=N -> N-1之前的数据confirm)
HLEN 首部长度 4bit 可变,可以确定首部和数据的分界
保留 6bit
控制位 为 1 的时候
URG 紧急标志 尽快发送报文
ACK 确认标志,确认字段有效
PSH 推送标志,发送方立即发送缓冲区中的数据
RST 复位标志 有严重差错,立即释放连接
SYN 同步标志 表示请求连接
FIN 终止标志 数据发送完毕,释放连接
其他字段
窗口大小 16bit(接收窗口)
校验和 16bit
紧急指针16 bit
选项和填充 <= 40 字节
MSS 最大报文长度,控制数据大小提高利用率,default val = 536
窗口扩大 【RFC 1323】
时间戳【RFC 1323】
选择确认 SACK【RFC 2018】
数据 必须是16bit的倍数
伪首部 12 bit
验证TCP数据段是否传送到了正确目标端
源IP地址 32bit
目标IP地址 32bit
全0 8bit
协议 8bit
TCP总长度 16bit
可靠传输的实现
滑动窗口 字节为单位
通知窗口 or 发送窗口
可用窗口 or 有效窗口 = 允许发送数据但是未得到确认
滑动已经发送但是未收到确认的窗口 可用窗口++ 一段时间未确认进入超时重传
流量控制
通过调整窗口大小,让接收方来得及接收
拥塞控制
周而复始三种策略
慢启动
拥塞避免
超时重传
差错控制
假设AB之间的链接
RTT
U(利用率)= Td(Td+RTT+Ta)
TCP连接
阶段
连接建立
数据传送
连接释放
建立连接(三次握手)
客户端A 客户端B
主动打开——————————————被动打开
SYN-SENT——————————————LISTEN
—> SYN = 1,seq = x 我要连接
SYN = 1,ACK = 1,seq = y,ack = x + 1 <— 好,那就连接
ACK = 1,seq = x + 1,ack = y + 1 —> 好,我收到你的“好,那就连接”
ESTABLISHED <–same as right
———-数据传输————
连接释放(四次)
客户端A 客户端B
主动关闭——————————————被动关闭
———-数据传输————
ESTABLISHED <–same as right
FIN-WAIT-1 —>FIN = 1,seq = u 分手吧
—–尽快传输剩下的数据—–
FIN-WAIT-2 ACK = 1,seq = v,ack = u + 1 <— 此时通知应用进程 CLOSE-WAIT 可以,先把东西还给你
FIN = 1,ACK = 1,seq = w,ack = u + 1 <— 被动关闭 还完了
—》 ACK = 1,seq = u + 1(已经不传输数据,没必要+1),ack = w + 1 LAST-ACK 好,收到了你的东西
TIME-WAIT 此时A还需等待2MSL,防止新连接复用端口(下一次个连接不会出现上一次的报文段),还可以超时重传最后的FIN+ACK确认 让我再伤心一会,还不想着新的恋情
UDP
实现功能
复用分用
有限的差错检测
特点
无连接
最大努力交付
面向报文
无拥塞控制
一对多,一对一,多对多
首部开销小(对比TCP)8 vs 20字节
首部+数据一齐校验
格式
源端口 16bit
目的端口 16bit
UDP总长度 16bit
校验和 16bit
数据 16bit倍数
伪首部
源IP地址 32bti
目的IP地址 32bit
全0 8 bit
协议 8bit
UDP总长度 16bit
补充
降低UDP丢包率:
尽量使用大数据包