TCP协议详解

TCP协议的特点:面向连接 可靠地 字节流服务

面向连接

在传输数据之前必须建立连接 —>三次握手

在传输数据之前必须断开连接 —>四次挥手

TIME_WAIT状态存在的意义:

1.处理迟来的数据报,直接将其丢弃,防止对后续启动进程造成影响。

2.可靠的终止TCP连接,防止最后发送的ACK被丢弃。

TCP字节流服务

从应用层:

1.发送端send的次数和接收端recv的次数没有必然联系

2.recv在接受数据时,不需要一次将缓冲区的数据全部读取,剩余的数据会保存在TCP接受缓冲区中。

从内核:

1.发送端send的次数和内核封装的TCP报文段的个数没有必然联系

2.接收端recv的次数和接受到的TCP报文段的个数没有必然的联系

从数据:

1.发送的数据时没有明显的界限的。

TCP数据的粘包问题?

a.当连续发送数据时,由于tcp协议的nagle算法,会将较小的内容拼接成大的内容,一次性发送到服务器端,因此造成粘包

在两次send()之间使用recv()来阻止连续发送的情况发生。

b.当发送内容较大时,由于服务器端的recv(buffer_size)方法中的buffer_size较小,不能一次性完全接收全部内容,因此在下一次请求到达时,接收的内容依然是上一次没有完全接收完的内容,因此造成粘包现象。

由于产生粘包的原因是接收方的无边界接收,因此发送端可以在发送数据之前向接收端告知发送内容的大小即可。

可靠性传输

TCP协议头部结构

TCP的可靠性传输:

1.数据能够到达对方 应答确认 超时重传 滑动窗口 拥塞控制

2.到达的数据不重复、不乱序 32位序号

3.到达的数据不失真 16位校验和

滑动窗口

保证发送方发送数据的速率与接收方接受数据的速率相匹配

窗口

TCP头部结构中16位的窗口大小–>接受通告窗口:他由接收方填充,来通告发送方当前接收方的接受缓冲区中还能容纳的数据大小。决定了发送方的数据的窗口大小。接受通告窗口会随着接收方的应用程序的数据处理动态变化。

滑动

发送方首先根据接受通告窗口决定本端的能够发送的数据窗口,这个窗口的位置会随着收到接收方的确认报文段不断地向后移动,并且窗口的大小也会随着接受通告窗口的值,大小也会不断变化。

窗口为0,如果出现这种情况怎么办?

如果发送方得知接受窗口为0后,便不在发送,会定期发送窗口探寻,直到定时器结束。

糊涂窗口综合征

糊涂窗口综合症是指当发送端应用进程产生数据很慢、或接收端应用进程处理接收缓冲区数据很慢,或二者兼而有之;就会使应用进程间传送的报文段很小,特别是有效载荷很小; 极端情况下,有效载荷可能只有1个字节;传输开销有40字节(20字节的IP头+20字节的TCP头) 这种现象。

如果是发送方为产生数据很慢的服务,比如一次产生一个字节,一次发送一个字节,为了防止发送端的TCP逐个字节的发送数据,发明了Nagle算法。

Nagle算法

基本定义:任意时刻,最多只能有一个未被确认的小段。在未收到该小段的ACK之前不能发送其他的数据。

小段是小于指定发送尺寸大小的数据块,未被确认是指没有收到对方发送的ACK。

拥塞控制

控制发送方发送数据的速率与网络环境相匹配

滑动窗口和拥塞控制都是为了数据在网络传输过程中减小丢包率。

  • 慢启动:刚开始传输时,以一个很小的值发送,来看下网络环境,然后慢慢增加报文段的大小(乘二的方式增加报文段大小),直到达到慢启动门限的大小。
  • 拥塞避免:然后进入拥塞避免阶段,这时候就不是以乘二的大小来增加报文段的大小了。直到收到3个重复的确认(看最后一个图),
  • 快速重传:立即传输丢失的报文段。
  • 快速恢复:将报文段大小降到当前大小的一半,然后又开始进入拥塞避免的阶段,这是一个循环的的过程。