客户端timewait

客户端timewaitSocket中的TIME_WAIT状态在高并发短连接的server端,当server处理完client的请求后立刻closesocket此时会出现time_wait状态然后如果client再并发2000个连接,此时部分连接就连接不上了,用linger强制关闭可以解决此问题,但是linger会导致数据丢失,linger值为0时是强制关闭,无论并发多少多能正常连接上,如果非0会发生部分连接不上…

大家好,又见面了,我是你们的朋友全栈君。

客户端timewait

Socket中的TIME_WAIT状态

在高并发短连接的server端,当server处理完client的请求后立刻closesocket此时会出现time_wait状态然后如果client再并发2000个连接,此时部分连接就连接不上了,用linger强制关闭可以解决此问题,但是linger会导致数据丢失,linger值为0时是强制关闭,无论并发多少多能正常连接上,如果非0会发生部分连接不上的情况!(可调用setsockopt设置套接字的linger延时标志,同时将延时时间设置为0。

TCP/IP的RFC文档。TIME_WAIT是TCP连接断开时必定会出现的状态。
是无法避免掉的,这是TCP协议实现的一部分。
在WINDOWS下,可以修改注册表让这个时间变短一些

time_wait的时间为2msl,默认为4min.
你可以通过改变这个变量:
TcpTimedWaitDelay
把它缩短到30s

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对于我们来说往往是有利的。

客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口
状态为TIME_WAIT

是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?
有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?

主动关闭的一方在发送最后一个 ack 后
就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
这个是TCP/IP必不可少的,也就是“解决”不了的。
也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
   (经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
   在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
   fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
   主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。
TIME_WAIT 并不会占用很大资源的,除非受到攻击。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/135357.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • asp还有人用吗_javascript和jsp区别

    asp还有人用吗_javascript和jsp区别英文原文There’sanexistingStackOverflowquestionandexamplethatcallsExecuteAsynconRestSharp.NetCore.IsuccessfullyusedthatexamplewhenreferencingRestSharp.NetCore105.2.3withNewtonsoft.Json…

  • c++实现skipList「建议收藏」

    c++实现skipList「建议收藏」SkipList是一种随机化的数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(logn)平均时间)。基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表(因此得名)。所有操作都以对数随机化的时间进行。SkipList可以很好解决有序链表查找特定值的困难。跳表是平衡树的一种替代的数…

  • 思科静态路由配置_思科交换机trunk配置命令

    思科静态路由配置_思科交换机trunk配置命令1.配置静态路由路由器可以将不同网段之间的网络连接到一起,当路由器接收到数据包后要查看数据包中的目标IP,再检查自己的路由表,如果路由表中有和目标IP相匹配的路由条目,路由器才能将数据包按照该路由条目所指定的端口转发出去,实现不同网络之间的通信,那么路由器中的路由表是如何实现的呢?配置了路由器接口IP并为UP状态路由表中自动生成直连路由,对于非直连的路由,需通过静态路由管理员手工添加或通过配置动…

  • python 获取图片大小_python用户输入矩形的长和宽

    python 获取图片大小_python用户输入矩形的长和宽#coding:utf8fromPILimportImageimg=Image.open(“img.jpg”)printimg.sizeprintimg.format

  • Apple Silicon M1 Mac如何恢复出厂设置

    Apple Silicon M1 Mac如何恢复出厂设置今天小编就来和大家讲述一下AppleSiliconM1Mac如何恢复出厂设置并还原的?Apple完全改变的AppleSiliconMac的一个方面是访问恢复模式的方式,这是重新安装MacOS,解决问题或彻底擦除硬盘驱动器所必需的工具,以防万一您必须将其退回或决定删除硬盘。在下面,您将找到如何进入“恢复模式”,包括其中的工具,最后是如何完全重置M1Mac。新的恢复模式看起来很相似,但使用起来却有所不同。如何在AppleSiliconMac上访问MacOSRecovery

  • javaweb-爬虫-1-62

    javaweb-爬虫-1-62

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号