java-ee TCP

本文详细解析了TCP协议如何通过确认应答、超时重传、连接管理(三次握手和四次挥手)、滑动窗口、流量控制、拥塞控制等机制实现可靠通信,以及如何处理粘包问题和TCP异常情况。
摘要由CSDN通过智能技术生成

①确认应答机制

TCP将每个字节的数据进行了编号,当数据发送由A发送到B后,主机B接收到数据,将返回一个应答报文(ACK),每一个应答报文都有一个确认序列号。

如主机A发送的数据编号由1-1000,主机B接收到数据之后,将返回一个ACK,并且确认序列号为1001,即告诉主机A即将要发送的数据从哪里开始

②超时重传机制

1.数据发生丢包

当主机A给主机B发送数据时,由于网络拥堵的原因导致数据丢了,无法到达主机B,此时主机A会在特定的时间内等待主机B发送的确认应答,当主机A在特定的时间内没有等到主机B发送的确认应答时,就会进行重传。

2.确认应答丢包

当主机A给主机B发送数据,并且主机B接收到了数据并将确认应答进行返回,但是确认应答发生了丢失,使得主机A无法收到主机B的发来的确认应答,在特定时间内,主机A没有接收到主机B发送的确认应答,将数据重新进行发送。

主机B收到了主机A重复发送的数据,此时的TCP会在缓冲区中根据收到数据的序列号,进行去重

TCP针对多个包丢失,继续超时重传,但是每次丢包、超时等待时间就会变长,连续多次重传都无法得到ACK,TCP会尝试重置连接,当重置连接失效TCP就会关闭连接,放弃网络通信

TCP是如何实现可靠性的?

①确认应答机制;②超时重传机制

③连接管理机制

1.三次握手建立连接

握手:通信双方进行一次网络交互

建立连接一定是客户端主动发起的,断开连接可能是客户端也可能是服务端

SYN:同步报文段,一方要向另一方申请建立连接

四次挥手:通信双方各自给对方发送一个FIN(结束报文),在各自给对方返回ACK

三次握手:ACK和SYN是同一时机触发的,都是由内核完成

四次挥手:ACK和FIN是不同时机触发的,ACK是由内核完成的会在收到FIN的时候第一时间返回,FIN是应用程序代码控制的,在调用到Socket的Close方法的时候,才会触发FIN

④滑动窗口机制

滑动窗口大小取决于流量控制和拥塞控制

采用批量发送(一次发送多条数据)提高性能

窗口大小:无需等待确认应答就可以继续发送数据的最大值,窗口越大,网络吞吐率越高

当主机A发送数据:1-1000、1001-2000、2001-3000、3001-4000时,不需要等到主机B的确认应答机制ACK,直接发送;当主机A收到第一个ACK时,则滑动窗口向后移,继续发送第五个数据。

主机A发送数据:1-1000、1001-2000、2001-3000、3001-4000

当主机A接收到ACK时,滑动窗口向后移,发送数据4001-5000

情况①:当主机A的数据已经发送到主机B,但是主机B的确认响应丢失

此时并不会产生很大的问题。如当数据1-1000已经送到主机B,此时主机B的确认应答(1001)丢失,但是当主机B收到数据1001-2000时,主机B的确认应答(2001)此时已经说明收到了数据1-1000的数据并且也收到了1001-2000的数据

情况②:数据包直接丢失

如当主句B接收到数据1-1000,但是数据1001-2000发生丢失时,主机B会一直发送确认应答(1001),让主机A发送1001-2000的数据,当主机A发送数据到5000时,此时连续接收到三次同样的确认应答机制时,会将丢失的数据重新发送,当主机B接收到数据1001-2000的数据,因为主机A发送的数据到了5000,所以此时主机B的确认应答就是5001.

⑤流量控制机制:根据接收方接收缓冲区的大小

流量控制衡量接收方的处理能力

接受端将自己的接收缓冲区大小放入TCP首部中,通过ACK通知发送端,当发送端发现接收端的缓冲区快要满时,就会减慢自己的发送速度;当接受端的缓冲区为0时,此时发送端不在发送数据,但是要定期发送一个窗口探测数据段,将接受端的窗口大小告诉发送端

⑥拥塞控制

拥塞控制衡量传输路径的处理能力

发送端刚刚开始发送少量的数据来试探当前的网络拥堵状况,当发现并没有出现丢包现象时,发送端继续增加发送数据的大小,初期是按照指数增长规律。但是指数增长的速度非常快,为了防止一下就出现丢包现状,所以当指数增长的一定的时候,将换成线性的增长的趋势。当按照线性增长出现丢包状况时,即立马降回到较小的数据大小进行发送。

⑦延迟应答机制

通过延时让接收方应用程序趁机多消费点数据,此时反馈的窗口大小就会更大一点,此时发送的速率也能提高

⑧捎带应答机制

在延迟应答的基础上,让ACK搭顺车。

⑨面向字节流->粘包问题

当主机A给主机B连续发送了多个应用层数据报之后,这些数据都积累到主机B的接收缓冲区紧紧挨在一起,此时主机B的应用程序在读数据的时候难以区分从哪里读到哪里是一个完整的的应用层数据

解决:要明确两个包之间的边界

1.对于定长的包,保证每次都按照固定大小读取即可

2.对于变长的包,可以在包与包之间使用明确的分隔符

⑩TCP异常情况

1.进程终止;2.机器重启;3.机器断电/网线断开

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值