Code Monkey home page Code Monkey logo

Comments (20)

zengyuangai avatar zengyuangai commented on May 12, 2024 37

http://crystalwindz.com/unp_note_1/#%E9%9D%9E%E6%AD%A3%E5%B8%B8%E8%BF%9E%E6%8E%A5%E7%BB%88%E6%AD%A2

from daily-interview-question.

mhycy avatar mhycy commented on May 12, 2024 23

问题定义

  • A -> B 发起TCP请求,A端为请求侧,B端为服务侧
  • TCP 三次握手已完成
  • TCP 三次握手后双方没有任何数据交互
  • B 在无预警情况下掉线(类似意外掉电重启状态)

问题答案

结论

A侧的TCP链路状态在未发送任何数据的情况下与等待的时间相关,如果在多个超时值范围以内那么状态为<established>;如果触发了某一个超时的情况那么视情况的不同会有不同的改变。

一般情况下不管是KeepAlive超时还是内核超时,只要出现超时,那么必然会抛出异常,只是这个异常截获的时机会因编码方式的差异而有所不同。(同步异步IO,以及有无使用select、poll、epoll等IO多路复用机制)

原因与相关细节

<大前提>

基于IP网络的无状态特征,A侧系统不会在无动作情况下收到任何通知获知到B侧掉线的情况(除非AB是直连状态,那么A可以获知到自己网卡掉线的异常)

在此大前提的基础上,会因为链路环境、SOCKET设定、以及内核相关配置的不同,A侧会在不同的时机获知到B侧无响应的结果,但总归是以异常的形式获得这个结果。

<关于内核对待无数据传递SOCKET的方式>

操作系统有一堆时间超级长的兜底用timeout参数,用于在不同的时候给TCP栈一个异常退出的机会,避免无效连接过多而耗尽系统资源

其中,<TCP KeepAive>特性能让应用层配置一个远小于内核timeout参数的值,用于在这一堆时间超长的兜底参数生效之前,判断链路是否为有效状态。

<关于超时的各个节点>

以下仅讨论三次握手成功之后的兜底情况

TCP链路在建立之后,内核会初始化一个由<nf_conntrack_tcp_timeout_established>参数控制的计时器(这个计时器在Ubuntu 18.04里面长达5天),以防止在未开启TCP KeepAlive的情况下连接因各种原因导致的长时间无动作而过度消耗系统资源,这个计时器会在每次TCP链路活动后重置

TCP正常传输过程中,每一次数据发送之后,必然伴随对端的ACK确认信息。如果对端因为各种原因失去反应(网络链路中断、意外掉电等)这个ACK将永远不会到来,内核在每次发送之后都会重置一个由<nf_conntrack_tcp_timeout_unacknowledged>参数控制的计时器,以防止对端以外断网导致的资源过度消耗。(这个计时器在Ubuntu 18.04里面是300秒/5分钟)

以上两个计时器作为keepalive参数未指定情况下的兜底参数,为内核自保特性,所以事件都很长,建议实际开发与运维中用更为合理的参数覆盖这些数值

<关于链路异常后发生的操作>

A侧在超时退出之后一般会发送一个RST包用于告知对端重置链路,并给应用层一个异常的状态信息,视乎同步IO与异步IO的差异,这个异常获知的时机会有所不同。

B侧重启之后,因为不存有之前A-B之间建立链路相关的信息,这时候收到任何A侧来的数据都会以RST作为响应,以告知A侧链路发生异常

RST的设计用意在于链路发生意料之外的故障时告知链路上的各方释放资源(一般指的是NAT网关与收发两端);FIN的设计是用于在链路正常情况下的正常单向终止与结束。二者不可混淆。

<关于阻塞>

应用层到底层网卡发送的过程中,数据包会经历多个缓冲区,也会经历一到多次的分片操作,阻塞这一结果的发生是具有从底向上传递的特性。

这一过程中有一个需要强调的关键点:socket.send这个操作只是把数据发送到了内核缓冲区,只要数据量不大那么这个调用必然是在拷贝完之后立即返回的。而数据量大的时候,必然会产生阻塞。

在TCP传输中,决定阻塞与否的最终节点,是TCP的可靠传输特性。此特性决定了必须要有ACK数据包回复响应正确接收的数据段范围,内核才会把对应的数据从TCP发送缓冲区中移除,腾出空间让新的数据可以写入进来。

这个过程意味着,只要应用层发送了大于内核缓冲区可容容纳的数据量,那么必然会在应用层出现阻塞,等待ACK的到来,然后把新数据压入缓冲队列,循环往复,直到数据发送完毕。

from daily-interview-question.

BlingSu avatar BlingSu commented on May 12, 2024 18

懵逼状态。

from daily-interview-question.

JIAFENG123 avatar JIAFENG123 commented on May 12, 2024 1

当B机器突然重启时,TCP连接可能会经历一些状态变化。TCP(Transmission Control Protocol)是一种面向连接的协议,连接的建立和维护是通过一系列的状态来管理的。在这种情况下,A机器可能会发现连接状态发生变化,具体取决于TCP实现和配置。

一般而言,TCP连接可能经历以下状态:

ESTABLISHED(已建立):A和B机器之间的连接已经建立,正常通信。

CLOSE_WAIT(等待关闭):B机器可能在重启之前发送了一个关闭请求,A机器已经接收到该请求,并等待进行关闭。

TIME_WAIT(等待时间):A机器在发送最后的确认后进入TIME_WAIT状态,确保在网络中所有的数据包都被正确处理,以避免出现混乱。

CLOSED(已关闭):连接被正常关闭,A机器意识到连接已经关闭。

如果B机器突然重启,A机器可能会注意到连接状态的变化,从ESTABLISHED状态到CLOSED状态。然而,这也取决于具体的TCP实现和网络条件。在一些情况下,A机器可能会在检测到连接中断后立即将状态更改为CLOSED,而在另一些情况下,可能会经历CLOSE_WAIT和TIME_WAIT等状态,以确保连接的正常关闭。

---------- 来自chatgpt3.5

from daily-interview-question.

jjeejj avatar jjeejj commented on May 12, 2024

@ray1888 你给这个答案是建立一个新的 TCP连接,而题目我理解的是 B 重启之前的TCP连接中, A所在状态。
由于 AB 已经正常建立连接处于 ESTABLISHED 状态,B突然重启,相当于这个 TCP 连接没有正常关闭,B 没有向A FIN关闭信号。等待一段时间后 ,A会去关闭该连接 向B发送一个 FIN,等待 B回复ack同意关闭,此是A的状态 FIN WAIT.
可以讨论一下,我回答的也不全面

from daily-interview-question.

azl397985856 avatar azl397985856 commented on May 12, 2024

因为B会在重启之后进入tcp状态机的listen状态,只要当a重新发送一个数据包(无论是syn包或者是应用数据),b端应该会主动发送一个带rst位的重置包来进行连接重置,所以a应该在syn_sent状态

问题b重启了, b是怎么知道需要发送给a”一个rst位的重置包“呢

from daily-interview-question.

azl397985856 avatar azl397985856 commented on May 12, 2024

因为B会在重启之后进入tcp状态机的listen状态,只要当a重新发送一个数据包(无论是syn包或者是应用数据),b端应该会主动发送一个带rst位的重置包来进行连接重置,所以a应该在syn_sent状态

问题b重启了, b是怎么知道需要发送给a”一个rst位的重置包“呢

看了@zengyuangai 的连接, 有了答案。
b和a沟通过程双方有一份数据, b重启之后这份数据没有了,就会发送rst重置。

image

from daily-interview-question.

negativeentropy9 avatar negativeentropy9 commented on May 12, 2024

这么超纲

from daily-interview-question.

zhoubendong avatar zhoubendong commented on May 12, 2024

牛逼,刚入职的我不适合看这道题

from daily-interview-question.

zhoushoujian avatar zhoushoujian commented on May 12, 2024

对前端来说已经超纲了。
这时候对于A机器来说,如果是刚打开网页的时候,那么浏览器选项卡左上角图标这时候会一直转圈,如果在短时间内B机器重新启动服务了,A机器会连接成功,如果超过了A机器的等待时间,这条请求会挂掉

from daily-interview-question.

xiangnianni avatar xiangnianni commented on May 12, 2024

菜鸟路过

from daily-interview-question.

mhycy avatar mhycy commented on May 12, 2024

尝试答一下,欢迎各位拍砖....

from daily-interview-question.

0scarecrow0 avatar 0scarecrow0 commented on May 12, 2024

一脸懵逼

from daily-interview-question.

zlccns avatar zlccns commented on May 12, 2024

一脸懵逼

from daily-interview-question.

yygmind avatar yygmind commented on May 12, 2024

如果A 与 B 建立了正常连接后,从未相互发过数据,这个时候 B 突然机器重启,问 A 此时处于 TCP 什么状态?如何消除服务器程序中的这个状态?(超纲题,了解即可)

from daily-interview-question.

yinsw1994 avatar yinsw1994 commented on May 12, 2024

所以到底处于什么状态?😓 syn_sent ? FIN WAIT?

from daily-interview-question.

jianglin-wu avatar jianglin-wu commented on May 12, 2024

所以到底是什么状态?

from daily-interview-question.

Dylan0916 avatar Dylan0916 commented on May 12, 2024

有没有人话点的版本⋯

from daily-interview-question.

kingda avatar kingda commented on May 12, 2024

如果开启了keep-alive,中间无数据传输的话,会等到keep-alive过期时间才会断开,断开之前是ESTABLISHED。断开之后是CLOSED
如果没开keep-alive,中间无数据传输的话,一直都是ESTABLISHED。
只要中间有数据传输,会立马重发直到断开。

from daily-interview-question.

rwtfs avatar rwtfs commented on May 12, 2024

如果 B 机器突然重启,而 A 机器未能检测到此事件,那么此时 A 机器会一直等待 B 机器的响应,因为它并不知道 B 已经宕机。因此,A 机器处于 TCP 的连接状态,也就是说,它的连接状态是未断开的。

如果 A 机器检测到了 B 的重启事件(比如向 B 发送了一个数据包但没有得到响应),那么 A 机器就会认为 B 宕机了,此时 A 机器会关闭这个连接,此时 A 机器处于 TCP 的断开状态。

from daily-interview-question.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.