【Java EE】网络原理——TCP2

目录

1.TCP的核心机制:(十个)

1.4.滑动窗口

1.5.流量控制

1.6.拥塞控制

1.7.延时应答

1.8.捎带应答

1.9.面向字节流

1.9.1粘包问题

1.10异常情况

2.TCP小结

3.基于TCP的应用层协议

4.TCP和UDP的对比


1.TCP的核心机制:(十个)

补充:(面试题)如果服务器出现大量的TIME_WAIT,该怎么处理?

出现说明服务器触发了大量的主动断开的TCP连接操作,这样的操作对于服务器来说是不科学的,一般都是客户端主动断开的。

1.4.滑动窗口

TCP除了保证可靠传输之外,也希望能尽可能高效的完成数据传输。

提高传输效率的机制。

  • 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,上图的窗口大小就是4000个字节。
  • 发送前四个段的时候,不需要等待任何ACK,直接发送。
  • 收到第一个ACK后,滑动窗口向后移动,继续发送第五个字段的数据,依次类推。
  • 操作系统内核为了保护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉。
  • 窗口越大,则网络的吞吐率越高。

丢包情况,如何重传?

情况一:数据包已经抵达,ACK被丢了。

只要不是所有的ACK都丢了,也不需要进行任何处理,因为后续的ACk可以进行确认。

ACk确认序号的规则很巧妙的解决了问题。

情况二:数据包直接丢了。

  • 当某一段报文段丢失之后,发送端会一直收到1001这样的ACK,就像是在提醒发送端“我想要1001”一样。
  • 如果发送端主机连续三次收到了同样一个“1001”这样的应答,就会将对应的数据1001-2000重新发送。
  • 这个时候接收端收到了1001之后们再次返回的ACK就是7001(因为2001-7000)接收端旗帜之前就已经收到了,被放到了接收端操作系统内核的接受缓冲区中。
  • 这种机制就被称为“高速重发机制”(也叫“快重传”)。

对于丢包来说,数据已经到达,不用做任何处理。

对于数据丢失,只需要把缺失的数据给重传就可以了

超时重传和快速重传是否冲突呢?

不同的情况下,采用的不同的重传策略,快速重传相当于超时重传在滑动窗口的特殊变种。

1.5.流量控制

因此TCP支持根据接收端的处理能力,来决定发送端的发送速度,这个机制就叫做流量控制。

  • 接收端将自己可以接受的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACk通知发送端
  • 窗口大小字段越大,说明网络的吞吐量越高。
  • 接收端一旦发现做自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端。
  • 发送端接受到这个窗口之后,就会减慢自己的发送速度。
  • 如果接收端缓冲区满了,就会将窗口设置为0;这时发送方不再传送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送段。

接受方根据自身的处理能力,反向制约发送方的速度,使双方达成一个“平衡”。

1.6.拥塞控制

是为了解决在传输数据的过程中,中间出现的问题。

TCP引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

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

像上面这样的拥塞窗口增长速度,是指数级别的。“慢启动”只是指初始时慢,但是增长速度非常快。

  • 为了不增加的那么快,因此不能使拥塞窗口单纯的加倍。
  • 此处引入了一个叫做慢启动的阈值。
  • 当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长。
  • 当TCP开始启动的时候,慢启动阈值等于窗口最大值。
  • 在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1.

少量的丢包,我们仅仅只是触发超时重传;大量的丢包,我们就认为网络拥塞。

当TCP通信开始后,网络吞吐量会逐渐上升,随着网络发生拥堵,吞吐量回立刻下降。

  1. 慢启动:刚开始以比较小的窗口来传输数据(刚开始不知道网络是否拥堵)。
  2. 按照指数的方式扩大窗口(这里的“慢”说的是刚开始窗口大小比较小,传输速度慢(而不是增长速度慢))。
  3. 指数增长的过程中,达到某个阈值就会变成线性增长。
  4. 线性增长到一定程度会出现丢包,立即把窗口变小。
  5. 缩小方式有两种:(1)直接缩到底,然后在进行线性增长。(2)缩到一半位置,然后在进行线性增长。 

拥塞控制这里的窗口,影响发送速度。

流量控制窗口,也影响发送速度。这俩哪个窗口那个小,就听那个的

1.7.延时应答

如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小。

  • 假设接收端缓冲区为1M,一次收到了500k的数据;如果立刻应答,返回的窗口就是500k。
  • 但实际上可能处理端处理的速度很快,10ms之内就把500k数据从缓冲区消费掉了。
  • 在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来。
  • 如果接收端稍微等一会在应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M。

窗口越大,网络吞吐量就越大,传输效率就越高,我们的目标是保证网络不拥塞的情况下尽量提高传输效率。

那么所有的包都可以延时应答吗?

  • 数量限制:每隔n个包就应答一次。
  • 时间限制:超过最大延时时间就应答一次。

具体的数量和超过时间,依据操作系统不同也有差异;一般N取2,超时时间取200ms。

延时应答有两种方式:

(1)按照一定的时间来制定延时。

(2)按照收到的数据量

1.8.捎带应答

在延时应答的基础上,我们发现,很多情况下,客户端服务器在应用层上也是“一发一收”的。

提升效率的机制。、

1.9.面向字节流

创建一个TCP的Socket,同时在内核中创建一个发送缓冲区和接收缓冲区。

  • 调用write时,数据会先写入发送缓冲区中。
  • 如果发送的字节数太长,会被拆分成多个TCP的数据包发出。
  • 如果发送的字节数太短,就会先在缓冲区里等待,等到缓冲区长度差不多了,或者其他合适的时机发送出去。
  • 接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区。
  • 然后应用程序也可以调用read从接受缓冲区拿数据。
  • 另一方面,TCP的一个连接,既有发送缓冲区,也有接受缓冲区,那么对于这一个连接,既可以读数据,也可以写数据,这个概念叫做全双工。

 由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如:

  • 写100个字节数据时,可以调用一次Write写100个字节,也可以调用100次write,每次写一个字节。
  • 读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read100个字节,也可以一次read一个字节,重复100次。

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

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

  • 对于定长的包,保证每次都按固定的大小读取即可。
  • 对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置。
  • 对于变长的包,还可以在包与包之间使用明确的分隔符。

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

  • 对于UDP,如果还没有上层交付的数据,UDP的报文长度仍然在。同时,UDP是一个一个把数据交付为应用层,就有很明确的数据边界。
  • 站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收,不会出现“半个”的情况。
1.10异常情况
  • 进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别。(调用Close)
  • 机器重启:和进程终止的情况相同。
  • 机器掉电\网线断开:接收端认为连接还在,一旦接受端有写入操作,接收端发现连接已经不在了,就会进行reset。即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在,如对方不在,也会把连接释放。

2.TCP小结

可靠性:

  • 校验和
  • 序列号(按序到达)
  • 确认应答
  • 超时重传
  • 连接管理
  • 流量控制
  • 拥塞控制

提高性能:

  • 滑动窗口
  • 快速重传
  • 延时应答
  • 捎带应答

其他:

  • 定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等)

3.基于TCP的应用层协议

HTTP  HTTPS  SSH  Telent   FTP   SMTP 

4.TCP和UDP的对比

我们说了TCP是可靠传输,那么是不是TCP一定优于UDP呢??

  • TCP用于可靠传输的情况,应用于文件传输,重要状态更新等场景。
  • UDP用于对高速传输和实时性要求比较高的通信领域。

用UDP实现可靠传输(面试题)

参考TCP的可靠性机制,在应用层实现类似的逻辑;

例如:

  • 引入序列号,保证数据顺序。
  • 引入确认应答,确保对端收到了数据。
  • 引入超时重传,如果隔了一段时间没有应答,就会重发数据。

(1)引入确认应答(ack)

(2)引入序号和确认序号

(3)引入超时重传

最基本的可靠传输就已经具有雏形了。

还可以引入滑动窗口,引入流量控制,引入拥塞控制……

  • 36
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值