TCP协议
流量控制
接收端处理数据的速度是有限的.如果发送端发的太快,导致接收端的缓冲区被占满,这个时候如果发送端继续发送,就会造成丢包,进而引起丢包重传等等⼀系列连锁反应.因此,TCP支持根据接收端的处理能力,来绝对发送端的发送速度,这个机制就叫做流量控制.
流量控制是站在接收端的角度来制约发送端的.
1.接收端将自己可以接收的缓冲区大小放入TCP报文首部的"窗口大小"字段中,通过ACK告知发送端.
2.窗口大小字段越大,说明网络吞吐量越高.
3.接收端感应到缓冲区快慢时,就会将窗口大小设置为更小值放在ACK报文中告知发送端.
4.发送端接收这个ACK后会调整发送窗口的大小.
5.当窗口大小被设置为0时,发送端不再发送数据,隔一段时间进行"窗口探测",来获取接收端最新的窗口大小.

拥塞控制
在网络传输中,转发方的转发能力也是有限的,在不清楚转发方转发能力的情况下,贸然发送大量数据是很危险的,容易引起一系列问题.因此,TCP引入慢启动机制,先发送少量数据探探路,在决定发送数据的速率.
拥塞控制是站在转发方的角度制约发送方.
在进行滑动窗口时,窗口的真正大小是取流量控制和拥塞控制中获取的窗口大小的最小值来进行发送.
1.慢启动,刚开始发送数据时,窗口大小很小.
2.如果发送数据正常没有丢包,那么就要扩大窗口大小,增加发送速率,此时窗口大小的增长是指数型增长.
3.指数型增长不是一直进行下去的,在达到阈值后,会转变成线性增长.
4.在通信过程中遇到了丢包,就会降低窗口的大小,进行快恢复,并且根据刚才的窗口大小重新设置窗口大小的阈值.
图中ssthresh标识的是窗口大小的阈值.

延迟应答
如果接收方在接收到数据后,立刻返回ACK,那么返回的ACK中的窗口大小就会比较小.
假设,接收方的接收缓冲区有2MB,在接收1MB的数据后,立刻返回ACK,这个ACK的窗口大小就是1MB.如果让ACK的返回稍微延后,接收方就能"消化"一些缓冲区的数据,在等待的时间里接收方消化了0.5MB的数据,那么就让ACK中的窗口大小从1MB扩大到1.5MB.毕竟窗口越大,网络的吞吐量越高,TCP为了在不拥堵的前提下尽可能的提高网络的吞吐量,就引入了延迟应答.
延迟应答的目的是在允许的范围内,窗口尽可能的大.
也不是所有的包都要延迟应答,延迟应答有两个相关参数:
数量限制:每隔N个包必须应答一次.
时间限制:超过最大应答时间就应答一次.
这两个参数在操作系统中是可以设置的.
捎带应答
在延迟应答的基础上,发现很多客户端服务器在应用层是"一发一收"的,客户端给服务器发送请求后,服务器返回ACK和响应.那么这个ACK就可以搭一个顺风车,和响应报文一起发送给客户端(ACK报文中并没有载荷,只需要将响应报文的ACK位设置为1即可).捎带应答也不是必然发生的,如果在延迟应答的限度内,没有其他需要一起发送的数据,那么ACK也就无车可坐,捎带应答不会发生.
捎带应答可以减少一次报文的发送,进而减少一次报文的相关封装,分用,减少开支.

面向字节流
TCP的Socket创建时,会在内核中创建一个发送缓冲区和接收缓冲区.
要发送的数据会先存储在发送缓冲区中.如果要发送的数据太长,会被拆分为多个TCP的数据包发出;如果要发送的数据太短,就会留在发送缓冲区,等待数据的补充或找到其他合适的时机发送.
接收方接收到的数据会先存储在接收缓冲区中.应用程序就可以调用read读取接收缓冲区的数据.
TCP的一个链接,既有发送缓冲区也有接收缓冲区,既可以读数据也可以写数据,这个概念叫做全双工.
粘包问题
由于TCP协议是面向字节流的,那么在读取数据时,站在应用层的角度看到的是一串连续的字节数据,无法知晓哪里是一个完整的应用层数据包.
例如,接收缓冲区中收到了三个完整的数据包,内容分别是"aaa""bbb"与"ccc",在进行读取时,TCP可以畅通无阻的把这三个数据包一口气读取下来,为"aaabbbccc",也可以在中间进行停止,如"aaabb".那么TCP在读取时就无法知晓"aaa"是一个完整的数据包,"bbb"是一个完整的数据包.进而在处理数据包时出现问题.
应用层数据包在 TCP 的接收缓冲区中连成一片,就称为“粘包问题”.
如何解决粘包问题? 粘包问题发生的原因是无法分清数据包之间的界限.自然解决粘包问题只需要在应用层分清数据包之间的界限即可.
1.对于定⻓的包,保证每次都按固定⼤⼩读取即可.
2.对于变长的包,在包头的位置规定一个包的长度,即可知晓包的结束位置.
3.可以使用一些不会出现在数据包内容中的字符作为分隔符(保证内容中不会出现分隔符即可).
异常情况
在运行过程中,可能会遇到一些异常情况打破原有的平静.
1.进程终止:TCP的生命周期长于进程,进程终止后,仍能正常发送FIN进行四次挥手.
2.机器关机:此时,四次挥手不一定能进行完.如果四次挥手进行完毕,那么就能正常断开链接.如果没能成功完成四次挥手,最起码也能发送出一个FIN,在发送FIN之后,对端返回ACK和FIN,但是这个FIN是没有回应的,因为本端已经关机.那么对端在超时重传几次之后,就会单方面的断开连接.
3.机器断电/网线破损:
如果故障的是接收方,发送方在重传几次之后,就会尝试"复位",发送复位报文段重新链接,复位依旧无应答就会单方面的断开链接;
如果故障的是发送方,TCP内部内置了一个保活定时器,定期判断对端是否存活,当对端不在时会尝试复位,复位依旧无应答就会单方面断开链接.
TCP与UDP对比
TCP是面向连接的,可靠的,基于字节流的传输层协议.能提供有序,无丢失,无重复的数据传输。 常用于需要高可靠性的场景.TCP较为可靠稳定,但是传输速度慢,占用资源多.
UDP是无连接的,不可靠的,面向数据报的传输层协议.不保证数据的有序性,完整性或交付. 常用于对实时性要求高但可容忍部分丢包的场景.UDP不那么稳定,但是传输速度快.

被折叠的 条评论
为什么被折叠?



