TCP/IP小结

传输层重点协议

TCP协议的段格式

  • 源/目的端口号:表示数据从哪个进程来,到哪个进程去
  • 32位序号:为了满足全双工的安全机制而存在的,是指发送数据的位置,每发送一次数据,就累加一次该数据字节数的大小。序列号不会从0开始,而是在建立链接时,由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。此外,在建立连接和断开连接时发送的SYN包和FIN包虽然并不携带数据,但是也会作为一个字节增加对应的序列号。它有以下四个功能:

                1.保证基本的可靠性

                2.是数据可以按序到达

                3.支持超时重传

                4.高效

  • 4位TCP报头长度:表示该TCP头部有多少个32位bit(即有多少个4字节),因此最大长度是15 * 4 = 60。
  • 6个标志位:

        URG:紧急指针是否有效

        ACK:确认号是否有效

        PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

        RST:对方要求重新建立连接,我们把携带RST标识的称为复位报文段

        SYN:请求连接,我们把携带SYN标识的称为同步报文段

        FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段

  • 16位窗口大小:表示接收缓冲区中,剩余容量的大小(满了就不要再发了),填写的是自己的缓冲区剩余容量双方根据对方缓冲区的大小来决定发送数据的大小,这就叫做流量控制 ,是发送方通过在自己的TCP报头中填写窗口大小来进行控制的
  • 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。
  • 16位紧急指针:标识哪部分数据是紧急数据

TCP各种机制

TCP对数据传输提供的管控机制,主要体现在两个方面:安全和效率。
这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率。

确认应答机制(安全机制)

确认应答是实现可靠传输的最核心的机制。

TCP为每个字节的数据都进行了编号,即为序列号。

每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。有问有答才能使得传输变得更加可靠。

超时重传机制(安全机制)

简单来说,A发给B的数据,可能会因为网络拥堵等情况,B没收到。此时A会进行判断,如果过了一段时间B还是没有收到(没有响应),那么就进行重发。
但是,有可能B收到了,而且发出了响应,只是这个响应A没有收到而已。那么此时A再发送一份过去,相当于有两份一样的数据了。因此可以使用前面提到过的序列号来进行去重。

连接管理机制(安全机制)

在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接

三次握手:

客户端发送SYN给服务端,服务端接受进入SYN_RCVD状态;

服务端发送SYN+ACK给客户端,客户端进入ESTABUSHED状态;

客户端发送ACK给服务端,服务端进入ESTABUSHED状态,accept返回。

四次挥手:

客户端发送FIN给服务端,客户端进入FIN_WAIT_1状态,服务端为CLOSE_WAIT状态;

服务端发送ACK给客户端,客户端进入FIN_WAIT_2状态;

服务端发送FIN给客户端,服务端进入LAST_ACK状态,客户端进入TIME_WAIT状态,等待2MSL。

客户端发送ACK给服务端,服务端和客户端都进入CLOSED状态。

滑动窗口(效率机制)

刚才我们讨论了确认应答策略,对每一个发送的数据段,都要给一个ACK确认应答。收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。
既然这样一发一收的方式性能较低,那么我们一次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)。

如果丢包了,有以下两种方式进行重传:

情况一:数据包已经抵达,ACK被丢了。
这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认;
情况二:数据包就直接丢了。

当某一段报文丢掉的话,会使得发送端一直收到类似1001这也的ACK,如果我多次收到了这也的ACK,我也就知道了我1001-2000的数据丢了(因为正常逻辑ACK是会不断往上加的,一直收到重复的就说明有一段掉包了)。当我把丢掉的这部分补齐以后,是可以接着当前的序号继续读取的,因为中间这一段被接收端拿到存储在接受缓冲区了。(这种机制又叫高速重发控制,快重传)

流量控制(安全机制)

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。
因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow Control)
  • 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 "窗口大小" 字段,通过ACK端通知发
送端;
  • 窗口大小字段越大,说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;
  • 发送端接受到这个窗口之后,就会减慢自己的发送速度;
  • 如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一
个窗口探测数据段,使接收端把窗口大小告诉发送端。

接收端如何把窗口大小告诉发送端呢?回忆我们的TCP首部中,有一个16位窗口字段,就是存放了窗口大小信息;那么问题来了,16位数字最大表示65535,那么TCP窗口最大就是65535字节么?
实际上,TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是 窗口字段的值左移M位;

拥塞控制(安全机制)

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。
TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;

此处引入一个概念程为拥塞窗口
发送开始的时候,定义拥塞窗口大小为1;
每次收到一个ACK应答,拥塞窗口加1;
每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为
实际发送的窗口;

延时应答(效率机制)

如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小。
1.假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;
2.但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;
3.在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过
来;
4.如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是
1M;
一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;

那么所有的包都可以延迟应答么?肯定也不是;
数量限制:每隔N个包就应答一次;
时间限制:超过最大延迟时间就应答一次;

捎带应答(效率机制)

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 "一发一收" 的。意味着客户端给服务器说了 "How are you",服务器也会给客户端回一个 "Fine, thank you";
那么这个时候ACK就可以搭顺风车,和服务器回应的 "Fine,thank you" 一起回给客户端

粘包问题

首先要明确,粘包问题中的 "包" ,是指的应用层的数据包。
在TCP的协议头中,没有如同UDP一样的 "报文长度" 这样的字段,但是有一个序号这样的字
段。
站在传输层的角度,TCP是一个一个报文过来的。按照序号排好序放在缓冲区中。
站在应用层的角度,看到的只是一串连续的字节数据。
那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个
完整的应用层数据包。

 那么如何避免粘包问题呢?归根结底就是一句话,明确两个包之间的边界

对于定长的包,保证每次都按固定大小读取即可;例如上面的Request结构,是固定大小
的,那么就从缓冲区从头开始按sizeof(Request)依次读取即可;
对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位
置;
对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是程序猿自己来定
的,只要保证分隔符不和正文冲突即可);

思考:对于UDP协议来说,是否也存在 "粘包问题" 呢?

对于UDP,如果还没有上层交付数据,UDP的报文长度仍然在。同时,UDP是一个一个把数
据交付给应用层。就有很明确的数据边界。
站在应用层的站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收。
不会出现"半个"的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值