TCP的建立与终止——三次握手、四次挥手
1. UDP和TCP的区别UDP是一种不提供不必要服务的轻量级运输协议它仅提供最小服务。UDP是无连接的即在传送数据前不需要先建立连接没有握手过程远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付但是正是因为这样省去和很多的开销使得它的速度比较快比如一些对实时性要求较高的服务就常常使用的是UDP比如视频流、在线游戏和实时语音通话等。TCP提供面向连接的服务在传送数据之前必须先建立连接数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务但是正因为这样不可避免的增加了许多的开销比如确认流量控制等。常应用于网页浏览、电子邮件、文件传输等。二者的主要区别连接方式TCP是连接导向UDP是无连接可靠性TCP提供可靠传输UDP不保证可靠性数据传输TCP面向字节流UDP面向数据报性能UDP通常更快但不保证数据的正确性和顺序而TCP更稳定但相对较慢应用数据丢失常用的运输协议时间敏感文件传输不能丢失TCP不电子邮件不能丢失TCP不Web文档不能丢失TCP不因特尔电话/视频会议容忍丢失UDP是100ms流式存储音频/视频容忍丢失UDP是几秒交互式游戏容忍丢失UDP是100ms智能手机讯息不能丢失TCP是和不是2. TCP概述TCP把连接作为最基本的对象每一条TCP连接都有两个端点这种断点我们叫作套接字socket它的定义为端口号拼接到IP地址即构成了套接字例如若IP地址为192.3.4.16 而端口号为80那么得到的套接字为。192.3.4.16:80。3. TCP连接的建立三次握手三次握手Three-way Handshake其实就是指建立一个TCP连接时需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口建立TCP连接并同步连接双方的序列号和确认号交换TCP窗口大小信息。注意三次握手必须是一方主动打开另一方被动打开的首先TCP服务器进程先创建传输控制块TCB时刻准备接受客户进程的连接请求而客户端处于Closed状态服务器处于LISTEN监听状态。然后进行三次握手1第一次握手首先客户端向服务器发送一段SYN同步报文并指明客户端是初始化序列号是ISN其中首部的同步位为SYN1表示“请求建立新连接”;序号为seqx(x一般位1)SYN1的报文段不能携带数据但要消耗掉一个序号随后客户端进入SYN-SENT阶段。图片来源https://blog.csdn.net/kking_edc/article/details/109480520注SYN报文段SYN1的报文段不能携带数据但需要消耗掉一个序号2第二次握手服务器收到客户端的 SYN 报文之后会以自己的 SYN 报文作为应答并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN 1 作为ACK 的值表示自己已经收到了客户端的 SYN此时服务器处于SYN_RCVD的状态。在确认报文段中SYN1ACK1确认号ackx1初始序号seqy。不要将确认序号ack与标志位中的ACK搞混了确认方ack发起方Seq1两端配对图片来源https://blog.csdn.net/kking_edc/article/details/109480520注SYNACK报文也不能携带数据但是同样要消耗一个序号3第三次握手客户端收到 SYN 报文之后会发送一个 ACK 报文当然也是一样把服务器的 ISN 1 作为 ACK 的值表示已经收到了服务端的 SYN 报文此时客户端处于ESTABLISHED状态。服务器收到 ACK 报文之后也处于ESTABLISHED状态此时双方已建立起了连接。确认报文段ACK1确认号acky1序号seqx1初始为seqx第二个报文段所以要1ACK报文段可以携带数据不携带数据则不消耗序号。图片来源https://blog.csdn.net/kking_edc/article/details/109480520注ACK报文段可以携带数据但是如果不携带数据则不消耗序号3.1 为什么TCP客户端最后还要发送一次确认一句话主要防止已经失效的连接请求报文突然又传送到了服务器从而产生错误。如果使用的是两次握手建立连接假设有这样一种场景客户端发送了第一个请求连接并且没有丢失只是因为在网络结点中滞留的时间太长了由于TCP的客户端迟迟没有收到确认报文以为服务器没有收到此时重新向服务器发送这条报文此后客户端和服务器经过两次握手完成连接传输数据然后关闭连接。此时此前滞留的那一次请求连接网络通畅了到达了服务器这个报文本该是失效的但是两次握手的机制将会让客户端和服务器再次建立连接此时客户端认为自己只有一个连接但是服务器认为有两个连接导致不必要的错误和资源的浪费。如果采用的是三次握手就算是那一次失效的报文传送过来了服务端接受到了那条失效报文并且回复了确认报文但是客户端不会再次发出确认。由于服务器收不到确认就知道客户端并没有请求连接。那么如何通过三次握手解决该问题参考下图图片来源https://blog.csdn.net/kking_edc/article/details/109480520如果一个「旧 SYN 报文」比「最新的 SYN」 报文早到达了服务端一次握手那么此时服务端就会回一个 SYN ACK 二次握手报文给客户端此报文中的确认号是 91901。客户端收到后发现自己期望收到的确认号应该是 100 1而不是 90 1于是就会回RST 报文三次握手。服务端收到RST报文后就会释放连接。后续最新的 SYN 抵达了服务端后客户端与服务端就可以正常的完成三次握手了。当第三次握手失败时服务器并不会重传ack报文而是直接发送RST报文段进入CLOSED状态。这样做的目的是为了防止 SYN洪泛攻击。3.2 什么是半连接队列服务器第一次收到客户端的 SYN 之后就会处于 SYN_RCVD 状态此时双方还没有完全建立其连接服务器会把此种状态下请求连接放在一个队列里我们把这种队列称之为半连接队列。简单来说就是半连接队列用于存储那些已经通过了TCP三次握手的前两次握手即接收了客户端的SYN并回复了SYN-ACK但还未完成第三次握手的连接。图片来源https://blog.csdn.net/kking_edc/article/details/109480520全连接队列已经完成三次握手建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。半连接队列的工作原理当客户端向服务器发送SYN请求第一次握手时服务器会为这个请求分配资源并将这个连接放入半连接队列中同时向客户端回复SYN-ACK第二次握手。客户端收到SYN-ACK后回复ACK第三次握手服务器收到ACK后才会将该连接从半连接队列移到全连接队列并认为该连接已经完全建立可以开始通信。如果客户端没有在超时时间内回复ACK如因网络延迟或故意攻击服务器会在超时后将这个半连接从队列中移除。针对上面最后一条如果服务器发送完SYN-ACK包未收到客户确认包服务器将进行首次重传等待一段时间仍未收到客户确认包进行第二次重传。如果重传次数超过系统规定的最大重传次数系统将该连接信息从半连接队列中删除。每次重传等待的时间不一定相同一般会是指数增长例如间隔时间为 1s2s4s8s……3.3 半连接队列被填满或遇到SYN洪泛攻击是如何处理当半连接队列被填满或遇到SYN洪泛攻击时服务器的TCP连接管理会受到严重影响。这种情况下服务器可能无法正常接收新的连接请求导致拒绝服务。1半连接队列被填满半连接队列在上面的问题中已经详细说过它是用于存储那些完成了TCP三次握手的前两次握手SYN和SYN-ACK但还未完成第三次握手ACK的连接它的容量是有限的由服务器的配置决定。当客户端向服务器发送SYN请求时服务器会将这个连接放入半连接队列并向客户端发送SYN-ACK响应。如果半连接队列中的连接数量超过了其容量上限就表示队列已被填满。当队列被填满后服务器将无法处理新的SYN请求因为它已经没有空间存储新的半连接。这时服务器可能会丢弃新的SYN包导致新的连接无法建立。半连接队列填满的原因正常情况下如果服务器的负载很高并且有大量合法客户端同时尝试连接半连接队列可能会短暂填满。攻击情况下在SYN洪泛攻击中攻击者故意发送大量的SYN请求并不回复ACK以使半连接队列快速填满从而导致服务器无法接受新的合法连接。2什么是SYN洪泛攻击服务器端的资源分配是在二次握手时分配的而客户端的资源是在完成三次握手时分配的所以服务器容易受到SYN洪泛攻击。SYN攻击利用TCP协议的三次握手过程来耗尽服务器的资源Client在短时间内伪造大量不存在的IP地址并向Server不断地发送SYN包Server则回复确认包并等待Client确认由于源地址不存在因此Server需要不断重发直至超时这些伪造的SYN包将长时间占用未连接队列导致正常的SYN请求因为队列满而被丢弃从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。如何应对1检测 SYN 攻击非常的方便当你在服务器上看到大量的半连接状态时特别是源IP地址是随机的基本上可以断定这是一次SYN攻击。在Linux/Unix上可以使用系统自带的netstat命令来检测 SYN 攻击。netstat -n -p TCP | grep SYN_RECV2SYN Cookie当服务器检测到半连接队列即将被填满或受到SYN洪泛攻击时通过使用SYN Cookie解决在linux中通过tcp_syncookies参数来应对这件事服务器不在半连接队列中分配空间而是将序列号经过加密算法生成一个Cookie并发送给客户端。客户端回复的ACK中会带上这个SYN Cookie。服务器通过这个Cookie验证连接的合法性从而不依赖半连接队列的大小。这种方式即使在遭受攻击时也能确保服务器继续接收并验证新的连接请求。千万别用tcp_syncookies来处理正常的大负载的连接的情况。因为SYN Cookie是妥协版的TCP协议并不严谨。对于正常的请求你应该调整三个TCP参数可供你选择第一个是tcp_synack_retries可以用他来减少重试次数服务器发出第二个是tcp_max_syn_backlog可以增大SYN连接数第三个是tcp_abort_on_overflow处理不过来干脆就直接拒绝连接了。3.4三次握手过程中可以携带数据吗其实第三次握手的时候理论上是可以携带数据的。但是第一次、第二次握手不可以携带数据。为什么这样呢?大家可以想一个问题假如第一次握手可以携带数据的话如果有人要恶意攻击服务器那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常然后疯狂着重复发 SYN 报文的话这会让服务器花费很多时间、内存空间来接收这些报文。也就是说第一次握手不可以放数据其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话此时客户端已经处于 ESTABLISHED 状态服务器此时还未处于 ESTABLISHED 状态。对于客户端来说他已经建立起连接了并且也已经知道服务器的接收、发送能力是正常的了所以能携带数据也没啥毛病。虽然第三次握手理论上可以携带数据但通常不这样做这是因为确保连接的稳定性三次握手的主要目的是建立一个可靠的连接以确保双方的发送和接收能力正常。如果在连接建立之前就传输数据而连接建立失败那么这些数据就可能丢失。安全性三次握手阶段的数据传输还没有经过完整的安全和可靠性验证因此传输数据可能不安全。协议规范标准的TCP协议并不推荐在SYN和SYN-ACK包中携带数据以减少复杂性并确保握手的过程专注于连接建立。例外虽然标准的三次握手过程不携带数据但有一些TCP优化技术允许在三次握手的第三次握手ACK包中携带数据。这种优化被称为“TCP Fast Open”。TCP Fast Open (TFO)是一种优化技术可以在第三次握手中携带数据。这需要客户端和服务器都支持TFO并且客户端在第一次握手时发送一个TFO Cookie。当客户端和服务器在后续的连接中都使用这个Cookie时客户端可以在三次握手的过程中携带数据从而减少延迟。总结TCP三次握手过程中客户端可以携带数据但为了标准性一般不这么做第一次、第二次握手不可以携带数据。但是在一些优化情况下如TCP Fast Open可以在第三次握手过程中携带数据提高传输效率。3.5ISN(Initial Sequence Number)是固定的吗对于连接的3次握手主要是要初始化Sequence Number 的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number缩写为ISNInital Sequence Number。这个号要作为以后的数据通信的序号以保证应用层接收到的数据不会因为网络上的传输的问题而乱序TCP会用这个序号来拼接数据.当一端为建立连接而发送它的SYN时它为连接选择一个初始序号。ISN随时间而变化因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送而导致某个连接的一方对它做错误的解释。三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number)以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的攻击者很容易猜出后续的确认号因此 ISN 是动态生成的。3.6 一个包数据可能会被拆成多个包发送如何处理丢包问题在TCP协议中当一个数据包过大或者需要适应网络传输情况时数据可能会被拆成多个包发送一般通过数据拆分与组装对数据进行处理。当数据被拆分成多个TCP包发送时TCP会为每个包分配一个序列号Sequence Number这些序列号用于标识每个包在整个数据流中的位置。接收端根据序列号来重组这些包以确保所有数据按照正确的顺序重新组装。该序列号和握手过程中的ISN有紧密的关系一旦三次握手完成ISN就成为后续数据传输中序列号的基准点客户端发送的第一个数据包客户端发送的第一个数据包的序列号是ISN_C 1这个“1”是因为ISN本身被用来标识SYN包。服务器发送的第一个数据包同样服务器发送的第一个数据包的序列号是ISN_S 1。从这个基准序列号ISN 1开始后续的数据包序列号会递增增量为每个数据包的字节数。下面介绍如何对数据包进行检测以及处理丢包的检测与处理机制a. 确认机制ACK当接收端成功接收到一个数据包时它会返回一个 确认包接收端需要回复一个ACK序列号长度确定该数据包已成功被接收给发送端告知其接收到的数据序列号。如果发送端在一定的时间内超时时间没有收到某个数据包的ACK接收端发送的ACK序列号长度并发送端会将其作为下一数据包的起始序列号就会认为该数据包可能丢失了b. 超时重传Timeout Retransmission当发送端没有在预定的超时时间内收到ACK时它会认为这个数据包丢失了并重传这个包。TCP使用动态超时重传机制即根据网络的延迟情况调整超时时间以提高丢包检测的效率。c. 快速重传Fast Retransmit如果接收端收到一个数据包但发现中间的一个数据包丢失了例如收到序列号为1、3、4的包但序列号2的包丢失它会重复发送对序列号2的重复确认Duplicate ACK。当发送端收到连续的三个重复确认Triple Duplicate ACKs时就会触发快速重传机制立即重发那个丢失的数据包而不必等待超时。3.7 三次握手总结三次握手建立连接的首要目的是同步序列号。只有同步了序列号才有可靠的传输TCP 协议的许多特性都是依赖序列号实现的比如流量控制、消息丢失后的重发等等这也是三次握手中的报文被称为 SYN 的原因因为 SYN 的全称就叫做 Synchronize Sequence Numbersa. 客户端客户端发送 SYN 开启了三次握手之后客户端连接的状态是 SYN_SENT然后等待服务器回复 ACK 报文。正常情况下服务器会在几毫秒内返回 ACK但如果客户端迟迟没有收到 ACK 会怎么样呢客户端会重发 SYN重试的次数由tcp_syn_retries参数在3.3中详细说过该参数以及yncookies控制默认是 6 次net.ipv4.tcp_syn_retries 6第 1 次重试发生在 1 秒钟后接着会以翻倍的方式在第 2、4、8、16、32 秒共做 6 次重试最后一次重试会等待 64 秒如果仍然没有返回 ACK才会终止三次握手。所以总耗时是 1248163264127 秒超过 2 分钟。如果这是一台有明确任务的服务器可以根据网络的稳定性和目标服务器的繁忙程度修改重试次数调整客户端的三次握手时间上限。比如内网中通讯时就可以适当调低重试次数尽快把错误暴露给应用程序。b. 服务器当服务器收到 SYN 报文后服务器会立刻回复 SYNACK报文既确认了客户端的序列号也把自己的序列号发给了对方。此时服务器端出现了新连接状态是 SYN_RCVD。这个状态下服务器必须建立一个 SYN半连接队列3.2讲过来维护未完成的握手信息当这个队列溢出后服务器将无法再建立新连接3.3详细说过。如果 SYN 半连接队列已满只能丢弃连接吗并不是这样开启syncookies功能就可以在不使用 SYN 队列的情况下成功建立连接。syncookies 是这么做的服务器将序列号经过加密算法生成一个Cookie放在己方发出的 SYNACK 报文中发出当客户端返回 ACK 报文时客户端回复的ACK中会带上这个SYN Cookie取出该值验证如果合法就认为连接建立成功图片来源https://blog.csdn.net/kking_edc/article/details/1094805204. 四次挥手建立一个连接需要三次握手而终止一个连接要经过四次挥手这由TCP的半关闭half-close造成的。所谓的半关闭其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力比如服务器将自己的接收端关闭后仍可以接收来自客户端的发送请求只不过服务器无法进行回传。TCP 连接的断开一共需要发送四个包因此称为四次挥手。数据传输完毕后双方都可释放连接。最开始的时候客户端和服务器都是处于ESTABLISHED状态这里假设客户端主动关闭服务器被动关闭。1第一次挥手主动-被动客户端发送一个FIN 报文报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。即发出连接释放报文段FIN1序号sequu等于前面已经传送过来的数据的最后一个字节的序号加1并停止再发送数据主动关闭TCP连接进入FIN_WAIT1终止等待1状态等待服务端的确认。TCP规定FIN报文段即使不携带数据也要消耗一个序号。2第二次挥手(被动-主动)服务端收到 FIN 之后会发送 ACK 报文且把客户端的序列号值 1 作为 ACK 报文的序列号值表明已经收到客户端的报文了此时服务端处于CLOSE_WAIT状态。即服务端收到连接释放报文段后即发出确认报文段ACK1确认号acku1并且带上自己的序列号seqv服务端进入CLOSE_WAIT关闭等待状态TCP服务器通知高层的应用进程客户端向服务器的方向就释放了这时候处于半关闭状态即客户端已经没有数据要发送了但是服务器若发送数据客户端依然要接受。这个状态还要持续一段时间也就是整个CLOSE_WAIT状态持续的时间。客户端收到服务端的确认后进入FIN_WAIT2终止等待2状态等待服务端发出的连接释放报文段在这之前还需要接受服务器发送的最后的数据。3第三次挥手被动-主动如果服务端也想断开连接了和客户端的第一次挥手一样发给 FIN 报文且指定一个序列号。此时服务端处于LAST_ACK的状态。即服务端没有要向客户端发出的数据服务端发出连接释放报文段FIN1ACK1由于在半关闭状态服务器很可能又发送了一些数据假定此时的序列号为seqw确认号acku1服务端进入LAST_ACK最后确认状态等待客户端的确认。4第四次挥手主动-被动客户端收到 FIN 之后一样发送一个 ACK 报文作为应答且把服务端的序列号值 1 作为自己 ACK 报文的序列号值此时客户端处于TIME_WAIT状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态服务端收到 ACK 报文之后就处于关闭连接了处于CLOSED状态。即客户端收到服务端的连接释放报文段后对此发出确认报文段ACK1sequ1ackw1客户端进入TIME_WAIT时间等待状态。此时TCP未释放掉需要经过时间等待计时器设置的时间2MSL(最长报文段寿命)后客户端才进入CLOSED状态。服务器结束TCP连接的时间要比客户端早一些。四次挥手步骤如下图片来源https://gitcode.csdn.net/66c55ce4a0bc797cf7b649bd.html?dp_tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mjg0NzQ0NCwiZXhwIjoxNzI5NzM2OTYyLCJpYXQiOjE3MjkxMzIxNjIsInVzZXJuYW1lIjoibTBfNjMwODYxOTgifQ.IdWGuw8i52y5Bl_ybIBCykU8UlkEILXf5ePPFEIFa3gspm1001.2101.3001.6650.14.1 为什么客户端最后还要等待2MSLMSL是Maximum Segment Lifetime的英文缩写可译为“最长报文段寿命”它是任何报文在网络上存在的最长时间超过这个时间报文将被丢弃。为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK接着客户端再重传一次确认重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL而是在发送完ACK之后直接释放关闭一但这个ACK丢失的话服务器就无法正常的进入关闭连接状态总结需要等待2MSL的原因第一保证客户端发送的最后一个ACK报文能够到达服务器因为这个ACK报文可能丢失站在服务器的角度看来我已经发送了FINACK报文请求断开了客户端还没有给我回应应该是我发送的请求断开报文它没有收到于是服务器又会重新发送一次而客户端就能在这个2MSL时间段内收到这个重传的报文接着给出回应报文并且会重启2MSL计时器。第二防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后在这个2MSL时间中就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。第三如果主动方不保留TIME_TAIT状态而是直接CLOSE那么此时连接的端口恢复了自由身可以复用于新连接。然而被动方的 FIN 报文可能再次到达这既可能是网络中的路由器重复发送也有可能是被动方没收到 ACK 时基于 tcp_orphan_retries 参数重发。这样正常通讯的新连接就可能被重复发送的 FIN 报文误关闭。保留 TIME_WAIT 状态就可以应付重发的 FIN 报文当然其他数据报文也有可能重发所以 TIME_WAIT 状态还能避免数据错乱。为什么是2MSL不是1.5MSL或者其他值呢TIME_WAIT确保有足够的时间让对端收到了ACK如果被动关闭的那方没有收到Ack就会触发被动端重发Fin一来一去正好2个MSL .这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间定义这个连接的插口客户的IP地址和端口号服务器的IP地址和端口号不能再被使用。这个连接只能在2MSL结束后才能再被使用。4.2 为什么建立连接是三次握手关闭连接确是四次挥手1这是因为 TCP 不允许连接处于半打开状态时就单向传输数据所以在三次握手建立连接时服务器会把 ACK 和 SYN 放在一起发给客户端其中ACK 用来打开客户端的发送通道SYN 用来打开服务器的发送通道。这样原本的四次握手就降为三次握手了。但是当连接处于半关闭状态时TCP 是允许单向传输数据的。为便于理解我们把先关闭连接的一方叫做主动方后关闭连接的一方叫做被动方。当主动方关闭连接时被动方仍然可以在不调用 close 函数的状态下长时间发送数据此时连接处于半关闭状态。这一特性是 TCP 的双向通道互相独立所致却也使得关闭连接必须通过四次挥手才能做到。四次挥手的简单步骤在TCP连接中关闭连接是一个双向的过程客户端和服务器都需要分别关闭各自的发送通道当客户端发送FIN请求关闭发送通道时服务器可能还有数据要发送因此它会先回复ACK并在数据发送完毕后再发送FIN客户端收到服务器的FIN后再发送最后一个ACK确认这样才能确保连接彻底关闭简单来说三次握手是因为只需要确认双方的发送和接收能力即可但四次挥手需要双方各自关闭发送通道这个过程需要双方都能确认所有数据都已传输完毕并且各自关闭了发送和接收通道。2建立连接的时候 服务器在LISTEN状态下收到建立连接请求的SYN报文后把ACK和SYN放在一个报文里发送给客户端。而关闭连接时服务器收到对方的FIN报文时仅仅表示对方不再发送数据了但是还能接收数据而自己也未必全部数据都发送给对方了所以己方可以立即关闭也可以发送一些数据给对方后再发送FIN报文给对方来表示同意现在关闭连接因此己方ACK和FIN一般都会分开发送从而导致多了一次。4.3 如果已经建立了连接但是客户端突然出现故障了怎么办如果连接已经建立但客户端突然故障服务器不会立即发现它会持续等待客户端的数据。但TCP设有一个保活计时器服务器每收到一次客户端的请求后都会重新复位这个计时器时间通常是设置为2小时若两小时还没有收到客户端的任何数据服务器就会发送一个探测报文段以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应服务器就认为客户端出了故障接着就关闭连接。