感谢各位网友提供资料,在此进行整理后放到自己的文章中:
Google了半天,发现关于CLOSE_WAIT的问题一般是C的,Java似乎碰到这个问题的不多(这有一篇不错的,也是解决CLOSE_WAIT的,但是好像没有根本解决,而是选择了一个折中的办法)。接着找,由于使用了NIO,所以怀疑可能是这方面的问题,结果找到了这篇。顺着帖子翻下去,其中有几个人说到了一个问题—— 一端的Socket调用close后,另一端的Socket没有调用close.于是查了一下代码,果然发现Server端在某些异常情况时,没有关闭Socket。改正后问题解决。
时间基本上花在Google上了,不过也学到不少东西。下面为一张TCP连接的状态转换图
说明:虚线和实线分别对应服务器端(被连接端)和客户端端(主动连接端)。
结合上图使用netstat -na命令即可知道到当前的TCP连接状态。一般LISTEN、ESTABLISHED、TIME_WAIT是比较常见。
分析:
上面我碰到的这个问题主要因为TCP的结束流程未走完,造成连接未释放。现设客户端主动断开连接,最近需要上线的逻辑server由于需要与大量的后台server交互,今天突然发现有大量的close_wait产生,于是仔细研究了一下:
首先我们知道,如果我们的服务器程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
因为如果是CLIENT端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:
Client ---> FIN ---> Server
Client <--- ACK <--- Server
这时候Client端处于FIN_WAIT_2状态;而Server 程序处于CLOSE_WAIT状态。
Client <--- FIN <--- Server
这时Server 发送FIN给Client,Server 就置为LAST_ACK状态。
Client ---> ACK ---> Server
Client回应了ACK,那么Server 的套接字才会真正置为CLOSED状态。
Server 程序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Client,那么可能是在关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。
通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(这个时间外网服务器通常会做调整,要不然太危险了)。如果有个流氓特地写了个程序,给你造成一堆的CLOSE_WAIT,消耗
你的资源,那么通常是等不到释放那一刻,系统就已经解决崩溃了。
只能通过修改一下TCP/IP的参数,来缩短这个时间:修改tcp_keepalive_*系列参数有助于解决这个问题。
但是实际上,还是主要是因为我们的程序代码有问题,通常是如下问题:
比如被动关闭的是客户端。。。
当对方调用closesocket的时候,你的程序正在
int nRet = recv(s,....);
if (nRet == SOCKET_ERROR)
{
// closesocket(s);
return FALSE;
}
很多人就是忘记了那句closesocket,这种代码太常见了。
我的理解,当主动关闭的一方发送FIN到被动关闭这边后,被动关闭这边的TCP马上回应一个ACK过去,同时向上面应用程序提交一个ERROR,导 致上面的SOCKET的send或者recv返回SOCKET_ERROR,正常情况下,如果上面在返回SOCKET_ERROR后调用了 closesocket,那么被动关闭的者一方的TCP就会发送一个FIN过去,自己的状态就变迁到LAST_ACK.
分享到:
相关推荐
#### CLOSE - **功能**:关闭游标。 #### PREPARE - **功能**:为动态执行准备SQL语句。 #### EXECUTE - **功能**:动态地执行SQL语句。 #### DESCRIBE - **功能**:描述准备好的查询。 ### 六、变量 #### 局部...
1. 直接使用行为动词原形,如 "Close the door"。 2. 使用 "Be" 动词加形容词、名词或介词短语,例如 "Be quiet"。 3. "Let" 结构,如 "Let me help you",其中动词保持原形。 祈使句的否定句式通常在句首加上 "Don...
- 基本语法:`WAITFOR DELAY 'HH:MM:SS';` - 示例:`WAITFOR DELAY '01:02:03'; SELECT * FROM employee;` - **WAITFOR TIME** - 基本语法:`WAITFOR TIME 'HH:MM:SS';` - 示例:`WAITFOR TIME '23:08:00'; ...
例如:看(look),画画(draw/paint),读书(read),唱歌(sing),飞(fly),游泳(swim),烹调(cook),做(do),喜欢(like),走(go),玩(play),打开(open),关闭(close),有(have),得到...
- 其他命令如`SELECT`用于数据操作,`AVG`用于计算平均值,`OPEN`和`CLOSE`用于数据库操作等。 学习结构化程序设计能够帮助开发者编写更清晰、更易于理解的代码,提高软件的质量和可靠性。在VFP中,掌握这些基本...
教程将详细讲解如何使用系统调用进行进程控制(如fork、exec、wait)、文件操作(open、read、write、close)、网络通信(socket、connect、accept、send、recv)等。 3. **进程管理**:涵盖进程创建、终止、同步和...
- **学习与收藏价值**:本书提供的PDF文档清晰度高,适合用于学习和长期收藏。对于希望深入了解UNIX编程的专业人士而言,这是一份宝贵的学习资源。 #### 3. 核心知识点解析 ##### 3.1 进程控制 - **概念**:进程...
- `collect` (v.) 收集 → `collection` (n.) 收藏品 → `collector` (n.) 收藏家 - `make` (v.) 制造 → `maker` (n.) 生产者;制订者 → `made` (过去式/过去分词) - `consider` (v.) 考虑 → `consideration` ...
其他选项如`openWindow()`、`window()`和`close()`均不是标准方法。因此,正确答案为C。 ### 3. 宏操作的限制 - **知识点概述**:在Microsoft Access中使用宏时如何限制宏命令的操作范围。 - **细节说明**:宏条件...
- **关闭数据库**:关闭已打开的FoxPro数据库可以通过多种方法实现,如使用“VIEW”窗口中的“CLOSE”命令、在命令窗口中输入“USE”命令等。 - **索引查询命令**:用于索引查询的命令主要有SEEK、FIND和LOCATE......
- `WAIT...TO...`:等待用户输入并创建变量。 `@SAY...TO...`命令不是用来建立内存变量的,而是用来在屏幕上显示信息。 ### 17. Internet 的服务分类 - **知识点**: Internet服务的分类。 - **详细解释**: ...