`
grzrt
  • 浏览: 187676 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

socket中的TIME_WAIT状态

 
阅读更多

TCP要保证在所有可能的情况下使得所有的数据都能够被投递。当你关闭一个socket时,主动关闭一端的socket将进入TIME_WAIT状态,而 被动关闭一方则转入CLOSED状态,这的确能够保证所有的数据都被传输。当一个socket关闭的时候,是通过两端互发信息的四次握手过程完成的,当一 端调用close()时,就说明本端没有数据再要发送了。这好似看来在握手完成以后,socket就都应该处于关闭CLOSED状态了。但这有两个问题, 首先,我们没有任何机制保证最后的一个ACK能够正常传输,第二,网络上仍然有可能有残余的数据包(wandering duplicates),我们也必须能够正常处理。
通过正确的状态机,我们知道双方的关闭过程如下:

 


假设最后一个ACK丢失了,服务器会重发它发送的最后一个FIN,所以客户端必须维持一个状态信息,以便能够重发ACK;如果不维持这种状态,客户端在接 收到FIN后将会响应一个RST,服务器端接收到RST后会认为这是一个错误。如果TCP协议能够正常完成必要的操作而终止双方的数据流传输,就必须完全 正确的传输四次握手的四个节,不能有任何的丢失。这就是为什么socket在关闭后,仍然处于 TIME_WAIT状态,因为他要等待以便重发ACK。
如果目前连接的通信双方都已经调用了close(),假定双方都到达CLOSED状态,而没有TIME_WAIT状态时,就会出现如下的情况。现在有一个 新的连接被建立起来,使用的IP地址与端口与先前的完全相同,后建立的连接又称作是原先连接的一个化身。还假定原先的连接中有数据报残存于网络之中,这样 新的连接收到的数据报中有可能是先前连接的数据报。为了防止这一点,TCP不允许从处于TIME_WAIT状态的socket建立一个连接。处于 TIME_WAIT状态的socket在等待两倍的MSL时间以后(之所以是两倍的MSL,是由于MSL是一个数据报在网络中单向发出到认定丢失的时间, 一个数据报有可能在发送图中或是其响应过程中成为残余数据报,确认一个数据报及其响应的丢弃的需要两倍的MSL),将会转变为CLOSED状态。这就意味 着,一个成功建立的连接,必然使得先前网络中残余的数据报都丢失了。
由于TIME_WAIT状态所带来的相关问题,我们可以通过设置SO_LINGER标志来避免socket进入TIME_WAIT状态,这可以通过发送RST而取代正常的TCP四次握手的终止方式。但这并不是一个很好的主意,TIME_WAIT对于我们来说往往是有利的。

分享到:
评论

相关推荐

    解决TIME_WAIT过多造成的问题1

    这个问题是由于高并发短连接的TCP服务器上,服务器处理完请求后主动关闭连接,导致大量的socket处于TIME_WAIT状态。如果客户端的并发量持续很高,部分客户端就会显示连接不上。 解决这个问题的方法有很多,例如使用...

    TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题解决

    在 TCP 连接中,客户端和服务器端都可以处于不同的状态,例如 ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT 等 trạng thái。 CLOSE_WAIT 状态是 TCP 连接中的一种状态,它表示服务器端已经收到了...

    windows 2008 R2解决socket连接不释放补丁包_time-wait过多注册表改.rar

    修改注册表中的tcpip的TIMEWAIT回收时间属性值,需要重启后生效 在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名为TcpTimedWaitDelay的DWORD键,设置为十进制0,以缩短TIME_WAIT...

    TIME_WAIT.rar_C-means_linux 网络状态_linux c wait_tcp_unix 网络编程

    在Linux系统中,进行网络编程时,TCP连接的TIME_WAIT状态是至关重要的一个环节。TIME_WAIT状态是TCP连接生命周期中的最后一个阶段,对于理解和优化网络应用性能有着直接的影响。本资源"TIME_WAIT.rar"包含了关于这个...

    系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT1

    虽然TIME_WAIT状态有助于保证连接的可靠性,但它也可能导致资源占用过多,尤其是在高并发的服务器环境中。大量的TIME_WAIT连接会使可用的TCP端口资源耗尽,从而限制了新的连接建立。这也是为什么有些人会建议调整...

    减少Linux服务器过多的TIME_WAIT

    在Linux服务器环境中,当TCP/IP连接关闭后,服务器端的端口可能会进入TIME_WAIT状态,这是TCP协议设计的一部分。TIME_WAIT状态的目的是确保网络中不存在旧的、可能重复的数据包,从而避免对新连接造成干扰,并确保...

    TCP TIME_WAIT常见解决方法-hanwei_1049-ChinaUnix博客1

    TCP TIME_WAIT状态是TCP连接生命周期中的一个重要阶段,它发生在主动关闭连接的一方(通常称为客户端)在连接关闭后等待一段时间,以确保所有在网络中可能残留的数据片段都被接收并确认。这个阶段的存在是为了避免旧...

    [服务器性能优化]Linux下高并发socket最大连接数和sysctl(time_wait)设置

    本文将深入探讨如何优化Linux下的socket连接数以及如何调整sysctl参数,特别是time_wait状态的影响。这有助于提升服务器处理大量并发请求的能力,确保服务的稳定性和响应速度。 首先,我们需要了解socket连接数的...

    Netstat命令详解如何关闭TIME_WAIT连接如何查看nginx的访问流量[归类].pdf

    4. 关闭 TIME_WAIT 连接:使用 netstat -ant | grep TIME_WAIT | awk '{print $2}' | xargs kill -9 命令可以关闭 TIME_WAIT 连接。 网络连接状态详解: 网络连接状态可以分为 12 种可能的状态,前面 11 种是按照 ...

    TCP_SYNC基础

    TIME_WAIT 状态是一个非常重要的状态,它的主要目的是等待足够的时间让 ACK 包到达服务器端,以便确保连接的关闭。如果服务器端没有收到 ACK 包,会重新发送 FIN 包,直到服务器收到 ACK 包。TIME_WAIT 状态的等待...

    Java网络开发--T/TCP协议(续)

    4.4节进一步阐述了TIME_WAIT状态可能被截断的情况,即在T/TCP中,如果双方主机都支持C(连接选项),可以缩短TIME_WAIT状态的时间,降低资源消耗。 4.5节介绍了T/TCP的TAO(TCP Accelerated Open,TCP加速打开)...

    TCP状态转换图1

    6. **TIME_WAIT**: 主动关闭方发送ACK后,进入TIME_WAIT状态,等待足够时间确保对方收到ACK,然后进入CLOSED状态。这个状态的存在是为了防止旧的重复数据包被误解释为新的数据。 TIME_WAIT状态的重要性在于: - 它...

    tcp状态解析和windowsio说明

    9. **TIME_WAIT**: 发送最后的ACK包后,套接字进入TIME_WAIT状态,等待2MSL(最大分段生存时间)以确保网络中没有丢失的ACK。这是为了防止旧的数据包在网络中重新出现,导致新连接的混淆。 10. **CLOSE_WAIT**: ...

    [Socket]CLOSEWAIT.rar_Help!

    总的来说,Socket编程中的CLOSE_WAIT状态是网络通信中的常见问题,理解其含义并掌握处理方法对于开发稳定、高效的网络服务至关重要。通过阅读并分析【Socket]CLOSEWAIT.mht】文件,你应该能够找到具体问题的解决方案...

    mysql占用率达到99%

    3. **分析TIME_WAIT状态的连接原因**:TIME_WAIT状态是TCP连接生命周期中的一个正常阶段,但它会占用一定的系统资源。在高并发场景下,如果大量的连接都停留在TIME_WAIT状态,可能会导致新的连接无法建立,从而影响...

    setsockopt 设置socket 详细用法.doc

    在某些情况下,我们可能希望socket在调用`closesocket`后立即关闭,而不是经历TIME_WAIT状态。这可以通过设置`SO_DONTLINGER`选项来实现,确保socket的快速释放。 ```c BOOL bDontLinger = FALSE; setsockopt(s, ...

    Socket状态变迁图

    最初发送FIN的一方在收到对方的FIN包后进入TIME_WAIT状态,等待一段时间确保对方收到ACK,然后进入CLOSED状态,表示连接完全关闭。另一方在收到ACK后直接进入CLOSED状态。 以上就是Socket状态变迁的基本流程。在...

    socket 编程问题一览(01)1

    在这个话题中,我们将探讨几个关键的步骤和概念,包括`socket()`、`bind()`、`TIME_WAIT`状态以及`SO_REUSEADDR`选项。 首先,`socket()`函数用于创建一个socket,返回一个描述符,这个描述符就像文件描述符一样,...

Global site tag (gtag.js) - Google Analytics