前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP简介

TCP简介

作者头像
zy010101
发布2019-05-25 19:57:19
4450
发布2019-05-25 19:57:19
举报
文章被收录于专栏:程序员程序员

版权声明:本文为博主原创文章,转载请注明博客地址: https://cloud.tencent.com/developer/article/1433363

TCP是Transmission Control Protocol的缩写。他是一种面向有连接,可靠的传输层协议。

TCP是全双工的通信方式。TCP将应用层传递给它的数据包会进行分组,形成一个个小的数据包。

与UDP不同,TCP是“名副其实”的,它确实是对通信进行有力的控制的协议。可以在丢包时进行重发,可以对次序混乱的包排序。当然,它的面向连接的特性,还可以让它在确定对端确实存在的情况下才发送数据,因此它也能控制通信流量。

在TCP中,当发送端发送的数据成功到达接收端主机的时候,接收端主机会返回一个已收到消息的通知给发送端。这个消息叫做确认应答(ACK)。TCP就是通过ACK来实现可靠传输的。如果发送端在一段时间内没有等到ACK,那么就认为数据已经丢失,会进行重发。因此,即使在TCP传输过程中产生了丢包,仍旧能够保证数据的可靠传输。

当然,有时候接收端确实收到了数据,并且返回了ACK,但是发送端并未得到这个ACK(这个ACK在应答途中丢失了),那么发送端仍旧会重发数据包。当然还有情况,例如,ACK最终到达了发送端,但是是超时到达。这种情况下,发送端仍旧会重发数据包。以上这种接收端确实收到了,但是发送端仍旧进行了多次发送的情况对于接收端而言是非常糟糕的。它不仅浪费了流量去接受数据包,而且还需要丢掉重复的包。为此,TCP又引入了一种机制,它能够识别是否已经接受了数据,以及判断是否需要接受。

序列号:按照顺序给发送数据的每一个字节都标上的号码就是序列号。(初始序列号是随机生成的,之后的每一个序列号比前一个序列号大1)

接收端通过查询数据包的TCP首部中的序列号和数据长度,将自己下一步应该接受的序号作为ACK返送回去。这样TCP就能实现可靠传输。

那么问题就是如何确定这个重发超时的时间长短。理想情形下,应该是找到一个最小的时间,他能保证“确认应答一定能在这个时间内返回”。因此,这个时间就是一个随着网络环境不同而不同的值。在网络环境良好的情形下,它肯定所需要的时间段,在网络拥塞的情形下,需要的时间长。

但是,TCP要求尽量提供一个高性能的通信。为此,在每次发包时都会计算往返时间及其偏差。重发超时的时间比这个时间大一点即可。偏差是因为网络环境不是一个稳定的,它是会变化的。因此往返时间会有一个波动,导致产生偏差。但是TCP要求尽量不去浪费网络流量。在BSDUnix和Windows下,一般超时以0.5秒作为一个单位。因此重发超时是0.5的倍数。不过,由于最初的数据包不知道往返时间,所以一般设置为6s。数据包在多次重发以后,如果仍旧没有收到接收端的确认应答(ACK),就判定网络或者接收端出现异常,强制关闭连接,并且通知应用通信异常强行终止。

TCP是面向有连接的服务,它在通信正式开始之前,通过TCP首部发送一个SYN包,作为建立连接的请求,并等待确认应答。若果等到了确认应答,说明连接建立,否则认为连接未建立。在通信终止的时候,也会发送FIN包来确认终止连接。一般而言,TCP连接的建立与断开需要来回收发7个包才行。

在建立TCP连接的过程中,也可以确定收发数据包的大小(MSS),理想情形下,数据正好是IP中不会被分开处理的最大长度。MSS是在三次握手的时候,被通信双方计算出来的。

TCP以一个段为单位,每发一段进行一次确认应答。这种方式的缺点在于,若通信往返时间过长,那么通信效率越低。为了解决这个问题,TCP引入了窗口,用它来控制效率的下降。窗口的大小就是无需等待确认应答能发送的数据最大值。这个机制使用了大量的缓冲区,实现对多个段的同时确认应答。(这个滑动窗口机制和CPU的流水线指令设计的想法是类似的)。滑动窗口的引入在一定程度上减少了部分数据包的重发,假设现在序号为1000的数据包的ACK在传输途中丢失了,但是2000的序号被发送端接受了,那么发送端就不会再去重发序号为1000的数据包了。如果丢失某一段报文,接收端会提醒发送端重发,但是在窗口较大的时候,接收端会不断提醒发送端,当3次提醒以后,发送端就会重发。

还需要考虑的一个问题是发送端和接收端的收发速率匹配问题。如果出现发送端的发的太快,缓冲区存不下这种情况,接收端还是会请求发送端重发。这就导致网络流量的浪费。为此,TCP提供了流控制来让发送端根据接收端的实际能力控制发送的数据量。那就是接收端会告诉发送端自己可以接受的数据的大小。这个大小就窗口的大小。在TCP首部中专门有一个字段来存储窗口大小。这个窗口的大小不是不变的,他会随着接收端的情况而不断变。例如接收端满缓存的情形下,窗口的大小就会变成0。这个窗口大小的更新如果在传输途中遗失,那么通信就无法进行,因此,为了避免发生这种情况。发送端会隔一段时间发送一个窗口探测的数据段(仅仅只有一个字节)来更新窗口大小。

拥塞控制,在TCP刚开始的时候会通过一个慢启动的算法来进行发送数据的控制。因此TCP的网络吞吐量看起来就是在逐步占领网络带宽的感觉。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年01月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档