TCP和UDP
TCP | UDP | |
---|---|---|
传输层 | 传输层 | |
面向连接,可靠,全双工,连接可管理(不丢,顺序,无错) | 无连接,不可靠,一对一,一对多,多对一,多对多 | |
面向字节流:应用程序每次交给TCP一个数据块,存储与TCP缓冲区,作为无结构字节流,经TCP拆分,选适合长度发送 | 面向报文:应用层交给UDP的报文保留报文边界,原样发送,每次一个数据段,当过大时,由IP层分片(效率低) | |
传输单位 | TCP报文段 | 用户数据报 ip包中协议号17 |
优缺点 | 安全,速度,效率低,稳定,有状态 | 不安全,快,不稳定,无状态 |
机制 | 流量控制(滑动窗口) | 不分组,组装排序 |
差错控制(校验和) | 由应用层负责可靠,ip层提供不可靠包交换 | |
拥塞控制(慢开始-拥塞避免,快重传、快恢复) | 网不好时易丢包 | |
三次握手,四次挥手 | 少攻击 | |
确认机制(重传ARQ)耗时,占用资源,容易被攻击 | ||
应用 | 效率要求低,准确性高,要求有连接 | 效率要求高,准确性低 |
eg:文件传输(FTP,HTTP)准确,慢 | 即时通信(qq) | |
发送接受邮件(POP,IMAP,SMTP)准确,慢 | 在线视频 | |
远程登录(talent,SSH)准确,有连接 | 网络语音(TFTP) | |
编程模型 | ||
客户端连续发送&服务器缓存足够大 | 一次接收,无边界 | UDP多次连接,发一次,收一次,有边界 |
TCP
报头
源端口:2B,大于1023的16位数,由基于tcp应用的用户进程随机选择
目的端口:2B,由应用程序指定
顺序号:4B,32bit无符号数,范围0~2^32 -1,TCP源向目的发送数据字节流,用顺序号对每个字节计数,表示该报文段中第一个数据字节的顺序。当建立连接SYN=1时,表示该主机选择的该连接的初始顺序号ISN
确认号:4B,发送确认一端期望收到的下一个顺序号,当ACK=1时有效
数据偏移:4bit,报头中32bit字的数目(报头长度)
保留区域:6bit,未来使用,置0
控制位:6bit
URG | “1” 紧急指针有效 |
---|---|
ACK | “1” 确认号 |
PSH | “1” 接收方应尽快将报文交给应用层,不用等等缓冲区满 |
RST | 用于复位由于主机崩溃或者其他原因而出现的错误连接,拒绝非法报文段/连接请求。 当RST=1时必出问题 |
SYN | 同步序号 “1” 连接请求,用于建立连接和使序号同步 |
FIN | 释放连接 “1” 关闭本端数据流 |
窗口大小:2B,0~2^16 -1,从确认号开始源端可以接收的字节
校验和:2B,对整个TCP报文,发送端计算存储,接收端验证
紧急指针:2B,+顺序号=紧急数据最后一个字节的序号,URG=1时有效
选项和填充:4n B(保证为整数字节),连接方在通信的第一个报文段中指明该选项,指明本端能接收的最大长度报文段(MSS)
伪首部:
源ip(4B)+目的ip(4B)+0(1bit)+6(1bit)+TCP长度(2bit)
三次握手,四次挥手
目的:
-
消除旧连接请求SYN对新连接的干扰:当客户端多次发送SYN请求时,服务端则多次回应(SYN + ACK),客户端收到后判断当前连接是否为历史连接,如果是历史连接,就会发送终止报文给服务器终止连接;如果是正常连接,就会发送确认报文,进而建立连接。
如果只有两次握手,那么客户端识别请求后无法进行后续操作,如果是过期的请求就会造成错误的连接。 -
同步连接双方的确认号,序列号:防止数据包重复发送,以及数据包接收时顺序问题。
-
交换TCP窗口大小
三次握手后,得到双方序号,最大接收数据大小,以及MSS(最大分段大小)
MSS=MTU(以太网最大传输单元,一般为1500B)-IP头(20B)-TCP头(20固定+12可选)=1448B(1460B)
∴当应用层数据>MSS时,分段发送
- ACK 和 FIN 为什么不能合并发送?
服务器收到客户端的 FIN 就会立即触发 ACK,这个操作是由内核完成的。
服务器发送的 FIN 是由代码控制的,代码中出现了 socket.colse()这样的操作之后,才会触发 FIN。
确认机制(重传ARQ)
收到数据立刻返回ACK,表示收到,客户端发出数据而一段时间内没有收到ACK则认为数据丢失,重新发送该数据。
回复按序收到的最后一个序号的确认号(对最后一个数据重复确认)
∴多余ACK为冗余ACK
- 尽量不发ACK包(ACK包不消耗seq),最好发其他消息时捎带ACK
- 任何时候,不超过两个未确认的段(够两个就发ACK)
- 延迟确认收到数据后延迟200ms(看是否有其他数据发/收,满足①②)
- 当收到的段seq>预期的seq,立即发ACK(快重传)
- 收到重复段,丢弃包,立即发ACK(快重传)
- 收到缺失段,发ACK
重传机制
在往返时间RTT(TCP动态估算RTT)内未收到确认,则重传&下一次超时间隔=2倍的RTT
收到三个冗余ACK——>快重传
拥塞控制(慢开始、拥塞避免,快重传、快恢复)
设置拥塞窗口cwnd,阈值ssthresh
- 慢开始:拥塞窗口cwnd=1MSS,传输首次被确认则翻倍,直到cwnd=ssthresh
- 拥塞避免:每RTT,cwnd+1MSS,直到超时
- 快速恢复:每个冗余ACK,cwnd+1MSS
收到对丢失报文的ACK,降低cwnd,进入拥塞状态
若出现超时,进入慢开始状态
流量控制(滑动窗口)
窗口大小:无需等待确认应答而可以继续发送数据的最大值。
收/发双方各有一个窗口大小以及缓冲区
根据窗口大小,已发字节,期待字节,计算可发字节
根据窗口大小,客户端发送数据,无需等待服务端回复ACK,可以直接发送,窗口大小为0,无法继续接受
此时服务器确认一个(回复ACK),则窗口向后滑动
建立确认重传机制,收到ACK,移动窗口,防止对方发消息过快
按序确认
自动重传请求ARQ:
- 停止等待ARQ,窗口为“1”,不确认不发送,信道利用率低
- 连续ARQ:窗口(后退N帧),重传后面的
选择重传:将出错的帧后面的帧存于缓冲区,按顺序交给网络层,接受不按顺序
差错控制(校验和)
UDP
伪首部:
源ip(4B)+目的ip(4B)+0(1bit)+17(1bit)+UDP长度(2bit)
报头
源端口2B+目的端口2B+长度2B+校验和2B