TCP/UDP详解
1. TCP主要特点
1.面向连接
一对一、可靠、全双工通讯
2.面向字节流
TCP根据对⽅的接收能⼒和⽹络拥塞情况将字节流分成⼤⼩不同的段发送给接收缓存。
3.TCP的连接套接字连接两端的插⼝包含IP和端⼝号。全双⼯抽象连接。
TCP流量控制
接收⽅是通过调整滑动窗⼝来进⾏流量控制的。
死锁问题及解决:
A发送⼀个报⽂下次发送的序号为601,rwnd=400滑动窗⼝。但是如果这个报⽂丢失那么就会造成A不知道B中滑动窗⼝更新的消息那么就永远不会向B发送报⽂。
解决方案:持续计数器
只要收到对⽅的零窗⼝通知,就启动该持续计时器:
持续计时器到期发送⼀个零窗⼝探测报⽂段,对⽅再确认探测报⽂段时的窗⼝值。如果窗⼝值仍然是0,接收⽅确认报⽂⽅重新设置持续计数器;若窗⼝不是0,死锁的僵局便被打破了
TCP效率问题
TCP的3中发送时机:
1.发送缓存道达双方约定的MSS(最大缓存长度)
2.当URG(紧急位,立即将TCP发送缓存中的字节流打包成报文发送)=1
3.当发送方一个计时器期限到了
Nagle算法:为了解决效率低问题
发送⽅发送第⼀个字节,然后缓存剩下的数据字节。发送⽅收到对⽅发送的确认报⽂以后才把发送缓存中所有数据组装成⼀个报⽂段发送出去。
当发送缓存中数据达到对⽅接收窗⼝⼀半或者达到MSS时,⽴刻发送。
糊涂窗⼝综合症 :循环往复每次只能发⼀个字节
解决方案:接收⽅等待⼀段时间,使得接收缓存达到MSS,或者等到接收缓存已有⼀半空间;
只要出现这两种情况之⼀,接收⽅就发出确认报⽂,并向发送⽅通知当前窗⼝的⼤⼩。
拥塞控制
原因
1.链路容量不够,形成堆积
2.路由器缓存不够,在路由器发送堆积,对挤不下发生丢失
3.处理机太慢
拥塞控制与流量控制区别
- 流量控制是点到点,拥塞控制是全局性⽹络。
- 拥塞控制是防⽌过多数据注⼊到⽹络,控制发送速率。与流量控制有些相似。
- 流量控制是发送缓存与接收缓存的问题,拥塞控制是⽹络的问题
拥塞出现的指标
1.由于缓冲区不够⽽造成的分组丢失的百分数。
2.平均队列⻓度。
3.超时重传的分组数。
4.平均分组时延。
5.平均分组时延标准差。
拥塞控制算法
慢开始算法
目的:探测网络的负载或承受能力
发送⽅每接收到⼀个确认报⽂就将拥塞窗⼝增加⼀个报⽂段。 1、2、4、8、16。
慢开始⻔限ssthresh(状态变量)防⽌拥塞窗⼝cwnd增⻓过⼤引起⽹络拥塞。
• 当cwnd<ssthresh,使⽤慢开始算法。
• 当cwnd>sshresh,停⽌使⽤慢开始算法⽽使⽤拥塞避免⽅法。
• 当cwnd = sshresh时既可以使⽤慢开始算法也可以使⽤拥塞避免算法。
拥塞避免算法 :每经过⼀个RTT,cwnd = cwnd + 1,他的增⻓是线性的。
当出现⽹络拥塞时,ssthresh = max(cwnd/2,2);cwnd = 1,即门限设为拥塞窗口的一半,拥塞窗口设为1。重新开始慢开始算法。
⽬的:迅速减少⽹络中的分组数,有利于路由器将积压的分组处理完
快重传
接收⽅不要等待⾃⼰发送数据时才进⾏捎带确认,⽽是要⽴即发送确认,即使收到了失序的报⽂也要⽴即发出对已收到的报⽂段的重复确认。
发送⽅只需要⼀连收到3个重复确认就⽴即重传这样就不会出现超时。
快恢复算法
• 当发送端收到连续3个重复确认时,发送⽅认为⽹络很可能没有发⽣阻塞,因此不执⾏慢开始算法,⽽是执⾏快恢复算法;
• ssthresh = cwnd/2,cwnd = ssthresh; 慢开始门限设为拥塞窗口大小的一般,拥塞窗口大小设置为慢开始门限
• 开始执⾏拥塞避免算法,使拥塞窗⼝缓慢地线性增⼤。
TCP连接和断开
为什么两次握手不行?
第一次握手超时了,第二次握手建立连接,传输结束后。第一次握手才到,又建立新的连接,但这时已经不需要了。
错过了,就没必要了
三次握手原因:
协商起始字节编号
在第⼀、第⼆次握⼿过程中不可以携带数据的,但是在第三次握⼿过程中是可以携带数据的。
为什么客⼾端要等2MSL(报文最大生存时间)才关闭?
1.因为服务端要保证TCP全双⼯通信连接都能正确关闭,因为如果服务端没收到ACK那么就会再发⼀次FIN。那么客⼾端如果关闭,则⽆法回复ACKServer,就会收到RST⽽不是ACK。
- ⼀旦客⼾端直接进⼊CLOSED,很有可能端⼝号跟之前相同。然后上⼀次连接中有些数据滞留在⽹络,当你再建⽴连接时这些⽼的数据包会和新的数据混淆。等待2MSL(报文最大生存时间)基本上可以让这些⽼数据消失。
保活计时器
当建⽴连接之后⼀旦断⽹了,连接空闲时间达到两个⼩时以上,服务器⾃动发送探测报⽂段,若发送了10个报⽂段(每个相隔75秒)还没有响应,就假定客⼾除了故障,终⽌连接。
TCP黏包
⼀个数据包中包含了发送端发送的两个数据包的信息,那么就把这种现象叫做黏包。
接收端在收到这两个数据包的时候,要么是不完整的,要么是多出来⼀块,这种情况就是发⽣了黏包和拆包。
TCP黏包是怎么产⽣的?
发送端
发送的数据包⾮常⼩的时,TCP默认启⽤Nagle算法,将这些⾮常⼩的数据包进⾏合并发送(这个合并发送过程就是在发送缓冲区中进⾏的),发出来的数据就会是⼀个黏包的状态。
接收端
读取数据函数不能及时的把缓冲区中的数据拿出来,下⼀个数据的⼀部分就⼜到缓冲区中,读取的时候就是黏包。
怎么解决黏包和拆包?
1.每次读取固定⻓度的消息
如果当前读取到的消息不⾜指定⻓度,那么就会等待下⼀个消息到达后进⾏补⾜
2.通过分隔符处理
通过换行符或者用户指定的分隔符
3.在⽣成的数据包中添加⼀个⻓度字段,⽤于记录当前数据包的⻓度。
2. UDP特点:
- 不需要建⽴连接。
- 尽最⼤努⼒交付。
- ⾯向报⽂交付。
- 没有拥塞控制。
- ⽀持多种交互通信。
- ⾸部开销⼩仅有8字节。
- 应⽤程序必须选择合适的报⽂如果报⽂太⻓则需要IP分⽚,太⼩降低效率。
TCP vs UDP:
特征点 | TCP | UDP |
---|---|---|
是否连接 | 面向连接 | 面向非链接 |
传输可靠性 | 可靠 | 会丢包,不可靠 |
应用场景 | 传输量大 | 传输量小 |
速度 | 慢 | 快 |
- TCP是面向连接的,所以TCP有三次握手和四次挥手的过程;UDP无连接协议;
- TCP有可靠的连接机制;UDP没有连接和确认机制,会丢包、出错,是不可靠的协议;
- TCP协议:数据量很大,防止丢包,能保证正确重传,对数据准确性很关心; UDP:量小
- TCP:速度很慢,传输效率低;UDP:速度很快,传输效率很高。