JavaEE--TCP协议

目录

1.TCP协议的特点

2.TCP的报文结构

3.TCP协议的核心机制

3.1 确认应答

3.2 超时重传

3.3 连接管理

3.4 滑动窗口

3.5 流量控制

3.6 拥塞控制

3.7 延时应答

3.8 捎带应答

3.9 面向字节流

3.10 异常情况


1.TCP协议的特点

• 有连接:通信双方在建立连接之后才能进行通信

• 可靠传输:发送方会尽可能把数据发送给接受方,主要依靠“确认应答”机制

• 面向字节流:以字节为单位进行传输

• 全双工:一条链路,能够进行双向通信

2.TCP的报文结构

4位首部长度:报头的长度,4位是指单位是4字节

选项:可选项,如果选项没有,TCP报头长度是20字节(上图中除选项和数据外的5个纵格*4个字节),如果选项拉满,TCP报头长度是60字节,选项部分最大是40字节

保留(6位):TCP报头中提前申请的空间,以后用于其他用途
6位标志位:1) URG:紧急指针是否有效 2) ACK:确认号是否有效 3) PSH:提示接收端应用程序立刻从TCP缓冲区把数据冲走 4) RST:对方要求重新建立连接,携带RST标识的称为复位报文段 5) SYN:请求建立连接,携带SYN标识的称为同步报文段 6) FIN:通知对方,本端要关闭了,携带FIN标识的称为结束报文段

16位校验和:与UDP校验和相同

3.TCP协议的核心机制

3.1 确认应答

为了实现可靠传输,发送方在发送数据给接收方后,接收方需要返回一个用于应答的数据,即应答报文(表示标志位中的ACK,如果ACK为1则是应答报文),而在网络传输过程中,经常会出现“后发先至”的现象(发送方先发送数据一再发送数据二,结果先收到数据二的应答报文),为了解决这个问题,TCP给每个字节分配了一个序号(例如第一个字节编号为1,第二个字节编号为2),这个序号随字节向后推移而逐渐递增,同时TCP还引入了确认序号,取值为其应答数据的最后一个字节的序号+1。

左图即为确认应答机制的简单表示,整体的过程是A发送序号为1~1000的数据给B,B接受到A发送的数据并向A发送确认序号为1001的应答报文,此时说明B已经接受到了1~1000的数据,开始向A索要1001之后的数据,接着A发送序号为1001~2000的数据给B,B接受并返回确认序号为2001的应答报文。

3.2 超时重传

正常情况下,TCP通过确认应答机制来确定对方是否收到数据,而在网络传输过程中,可能会出现丢包等其他特殊情况,导致确认应答机制不能正常进行,这时就需要进行“超时重传”,简单来说就是把数据重新传输一遍。那么具体如何判断是否超时呢?如果发送方没有收到ACK,就会等待一定的时间(随着重传次数的增加,时间会越来越长),如果还没收到ACK,那么就判断出现了问题导致超时,从而去进行重传。如果重传了很多次还是没成功,在达到一定次数阈值后,就会触发复位报文(标志位中的RST)尝试重置连接。RST如果还没有效果,通信双方就会断开连接。

至于发送方为什么没有收到ACK呢?这又细分为两种情况(如下图)

第一种情况:数据在发送的时候发生丢包等其他问题,导致数据没有传输成功,A没有收到B发送的ACK,等待一定时间后,重新向B发送数据后成功收到B发送的ACK

第二种情况:接收方在发送ACK的时候发生丢包等其他问题,导致ACK没有传输成功,A没有收到B发送的ACK,等待一定时间后,重新向B发送数据后成功收到B发送的ACK(B接收了A发送的两次重复数据,但由于TCP中接收方会针对发送的数据去重,所以不会出现问题)

3.3 连接管理

连接管理分为建立连接和断开连接,TCP经过三次握手建立连接,四次挥手断开连接

• 建立连接:建立连接就是通信双方各自保存对端的信息,要完成这个过程需要进行三次网络交互(三次握手),首先客户端向服务器发送SYN(第一次握手一定是客户端先发起),服务器接收到SYN后向客户端发送ACK和SYN(ACK和SYN是同时发送的,可以合并),客户端接收到SYN后向服务器发送ACK

三次握手的意义:1) 相当于“投石问路”,在正式传输业务服务之前,先确认一下通信路径是畅通的2) 验证通信双方的发送能力和接收能力 3) 协商必要的参数,比如起始参数等等

三次挥手中的重要状态:1) LISTEN:服务器出现的状态,当服务器成功绑定端口后会进入到LISTEN状态 2) ESTABLISHED:连接建立完成,随时可以进行通信

• 断开连接:断开连接就是通信双方把之前保存的对方信息给删除掉,当客户端代码中调用close方法或者客户端进程结束时,触发断开连接机制,首先客户端向服务器发送FIN(第一次挥手客户端或服务器都可以主动发起,这里以客户端为例),服务器接收到FIN后向客户端发送ACK,发送完ACK之后向客户端发送FIN(ACK是在收到FIN后立刻返回,而FIN是在代码中调用close才触发,发送时间间隔较长,正常情况下不能合并,在“延时应答 ”的特殊情况下可以合并),客户端接收到FIN后向服务器发送ACK

四次挥手中的重要状态:1) CLOSE_WAIT(被动接收的一方的状态):等待应用调用close方法(如果代码中close没有及时调用或者根本没有调用,可能会出现大量的CLOSE_WAIT) 2) TIME_WAIT(主动发起的一方的状态):应对最后一个ACK丢包的场景,TIME_WAIT状态会等待可能重传过来的FIN,这个状态有一定的时间(一般是2MSL,MSL是网络中两个节点之间传输数据的最大时间),在这个时间内,如果没有接收到重传的FIN,说明最后一个ACK已经被对方收到,TIME_WAIT就释放了

3.4 滑动窗口

滑动窗口是一种提高传输效率的机制,在不引入滑动窗口之前,发送方需要等待接收到对方的ACK之后才发送下一个数据,这个过程比较低效,滑动窗口采用批量发送的方式,有效提高了等待时间的利用率。在这个机制中,无需等待ACK,可以继续发送数据的最大值,称为窗口大小。

上图就是滑动窗口的简单例子,其窗口大小是4000个字节。

滑动窗口虽然很大程度上提高了效率,但是也需要同时保证其可靠性,那么当滑动窗口出现丢包等问题时如何解决呢?首先我们来看滑动窗口发生丢包问题的两种情况。

第一种情况:ACK没有传输成功,发生这种情况时不需要做任何处理,后续的确认序号能够保证前面的数据都已经传输成功(图中确认序号为1001的ACK丢了,但是2001的确认序号成功接收到了,说明1~2000的数据都已经传输成功了)

第二种情况:数据没有传输成功,发生这种情况就需要等待数据重传(图中1001~2000的数据丢了,B会一直发送确认序号为1001的ACK,向A索要1001~2000的数据,等待A重传这部分数据并且B接收到后,数据就会开始继续传输)

3.5 流量控制

在滑动窗口机制中,窗口大小是可变的,窗口越大,单位时间发送的数据就越多,效率就越高,反之,窗口越小,效率就越低。我们都希望保证高效的传输,但如果发送速度太快,接收方处理不过来,就可能会引起丢包问题,这时就需要接收方根据自身的处理能力,反向制约发送方的速度,使双方达到平衡,这样的机制就称为“流量控制”。

如何衡量接收方的处理速度呢?接收方有一个接收缓冲区(阻塞队列),以空闲空间的大小作为发送方发送数据的窗口大小,把这个窗口大小告诉发送方,接收方会给发送方返回ACK,在ACK中,TCP会指定一个字段表示这个窗口大小,即TCP报文结构中的16位窗口大小(由于选项中有窗口扩展因子这个特殊属性,窗口大小可以非常大,而不是局限于64kb),整体的流程如下图

3.6 拥塞控制

与流量控制类似,拥塞控制也是和滑动窗口搭配的机制。发送方发送的速度不仅仅与接收方接收的速度有关,还要考虑传输过程中中间经过的交换机和路由器(中间链路上的节点)的转发能力,由于中间结构比较复杂,TCP将其视为一个整体,通过“实验”的方式来找到一个合适的窗口大小,这个过程就称为"拥塞控制"。

“实验”的简要流程:一开始以较低速度,小窗口来发送数据,如果没有出现丢包,说明中间链路畅通,就可以增加速度和窗口大小,直到增加到一定程度,发送速度非常快,出现了丢包,这时发送方立刻降低窗口大小,看还是否会出现丢包,如果不丢包,就继续增加窗口大小,反之降低窗口大小,持续这个过程直至找到合适的窗口大小,就可以实现不出现丢包问题的同时以较快速度传输。

3.7 延时应答

当发送方给接收方发送数据时,不会立即返回ACK,而是延长一定时间后再返回,这样的机制就称为“延迟应答”。

延时的作用:通过延时,可以给应用程序更多的时间去处理数据,使窗口大小得到提升,提高了传输的速度

延时的两种方式(通常结合使用):1) 按照一定的时间延时 2) 按照接收到的数据量延时

3.8 捎带应答

捎带应答是建立延时应答的基础上,提升效率的一种机制。客户端与服务器之间的通信,经常是“一问一答”的模型,正常情况下,ACK是内核收到请求后自动返回的,由于延时应答机制的存在,ACK不一定立刻返回,就可以和原来不同时返回的响应数据合并起来,这种机制就称为“捎带应答”。

3.9 面向字节流

在字节流读写数据的场景中,会涉及到一个关键的问题:粘包问题

假设上图是一个翻译服务器,需要把英文转为中文,服务器接收到发送的数据添加到接收缓冲区中,内容为helloworld并调用read读取请求,由于字节流的特点,读的时候可以一次读一个字节,也可以一次读多个字节,服务器无法区分哪个部分是一个完整的单词

那么如何解决粘包问题?要解决粘包问题,主要是需要区分哪个部分是一个完整的应用层数据包,大致有两种解决方法:1) 使用分隔符,分隔符是任意在请求数据中不存在的字符(分隔符以\n为例,上图接收缓冲区中内容\nhello\nworld) 2) 约定包的长度,先读取长度,再根据长度读取应用层数据包(例如上图接受缓冲区内容5hello5world)

3.10 异常情况

1) 进程崩溃:与进程正常结束相同,操作系统能够回收释放对应PCB中的文件描述符表,能够正常和对方进行四次挥手操作

2) 主机被关机(正常关机):操作系统会先尝试强制结束所有的用户进程,然后进入关机流程,同样的,在结束进程之后,会进行四次挥手(由于已经进入关机流程,四次挥手不一定都能够进行)。举个简单的例子:A和B建立连接,A马上要关机了,关机之前A向B发送FIN,B接收到FIN后返回ACK,接着B向A发送FIN,但是此时A已经关机,B会重传多次FIN,如果还是没有接收到ACK,那么就会与A断开连接

3) 主机电源掉电:由于发送方和接收方都可能发生掉电,所以这种异常存在两种情况,我们分别来看一下这两种情况

• 接收方掉电:发送方多次发送数据,但是没有收到接收方的ACK,接着发送方就会触发超时重传,重传几次还是没接收到ACK,会向接收方发送RST,RST也没有响应,发送方就会断开与接收方的连接 

• 发送方掉电:发送方无法发送数据,接收方在一定时间内没有收到发送方的数据后,接收方就会给发送方发送一个心跳包(没有载荷的数据包,用于触发ACK),如果发送方正常,就会给接收方返回ACK,反之,发送方不会有任何响应,在多次发送后如果还没有收到发送方的ACK,接收方就会断开与发送方的连接

4) 网线断开:在发送方和接收方之间的网线突然断开之后,发送方就会像上述接收方掉电的情况一样(触发超时重传→发送RST→断开连接),接收方会像发送掉电的情况一样(发送心跳包→断开连接)

  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值