- 浏览: 366203 次
文章分类
最新评论
-
strchi:
这个网站,什么都没有了
做小说搜索网站,这个是不是有可能会侵权的呢? -
从此醉:
楼主倒是给出解决办法啊
Java虚拟机支持的最大内存限制 -
kjmmlzq19851226:
又要增强客户体验,又要降低伪造攻击的概率,╮(╯▽╰)╭,程序 ...
Web安全测试之跨站请求伪造(CSRF)篇(图) -
zhangxinze:
linux下使用Java获取客户端ip地址?大家有何高见,我现 ...
怎样用Java来获取真实的IP地址 -
k_kid9157:
学习 感谢分享:-)
log4j的ConversionPattern参数的格式含义
CLOSE_WAIT状态的生成原因
首先我们知道,如果我们的Client程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
因为如果是Server端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:
Server ---> FIN ---> Client
Server <--- ACK <--- Client
这时候Server端处于FIN_WAIT_2状态;而我们的程序处于CLOSE_WAIT状态。
Server <--- FIN <--- Client
这时Client发送FIN给Server,Client就置为LAST_ACK状态。
Server ---> ACK ---> Client
Server回应了ACK,那么Client的套接字才会真正置为CLOSED状态。
我们的程序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Server,那么可能是在关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。
原因知道了,那么为什么不发FIN包呢,难道会在关闭己方连接前有那么多事情要做吗?
elssann举例说,当对方调用closesocket的时候,我的程序正在调用recv中,这时候有可能对方发送的FIN包我没有收到,而是由TCP代回了一个ACK包,所以我这边套接字进入CLOSE_WAIT状态。
所以他建议在这里判断recv函数的返回值是否已出错,是的话就主动closesocket,这样防止没有接收到FIN包。
因为前面我们已经设置了recv超时时间为30秒,那么如果真的是超时了,这里收到的错误应该是WSAETIMEDOUT,这种情况下也可以主动关闭连接的。
还有一个问题,为什么有数千个连接都处于这个状态呢?难道那段时间内,服务器端总是主动拆除我们的连接吗?
不管怎么样,我们必须防止类似情况再度发生!
首先,我们要保证原来的端口可以被重用,这可以通过设置SO_REUSEADDR套接字选项做到:
重用本地地址和端口
以前我总是一个端口不行,就换一个新的使用,所以导致让数千个端口进入CLOSE_WAIT状态。如果下次还发生这种尴尬状况,我希望加一个限定,只是当前这个端口处于CLOSE_WAIT状态!
在调用
sockConnected = socket(AF_INET, SOCK_STREAM, 0);
之后,我们要设置该套接字的选项来重用:
/// 允许重用本地地址和端口:
/// 这样的好处是,即使socket断了,调用前面的socket函数也不会占用另一个,而是始终就是一个端口
/// 这样防止socket始终连接不上,那么按照原来的做法,会不断地换端口。
int nREUSEADDR = 1;
setsockopt(sockConnected,
SOL_SOCKET,
SO_REUSEADDR,
(const char*)&nREUSEADDR,
sizeof(int));
教科书上是这么说的:这样,假如服务器关闭或者退出,造成本地地址和端口都处于TIME_WAIT状态,那么SO_REUSEADDR就显得非常有用。
也许我们无法避免被冻结在CLOSE_WAIT状态永远不出现,但起码可以保证不会占用新的端口。
其次,我们要设置SO_LINGER套接字选项:
从容关闭还是强行关闭?
LINGER是“拖延”的意思。
默认情况下(Win2k),SO_DONTLINGER套接字选项的是1;SO_LINGER选项是,linger为{l_onoff:0,l_linger:0}。
如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们一般采取的措施是“从容关闭”:
因为在退出服务或者每次重新建立socket之前,我都会先调用
/// 先将双向的通讯关闭
shutdown(sockConnected, SD_BOTH);
/// 安全起见,每次建立Socket连接前,先把这个旧连接关闭
closesocket(sockConnected);
我们这次要这么做:
设置SO_LINGER为零(亦即linger结构中的l_onoff域设为非零,但l_linger为0),便不用担心closesocket调用进入“锁定”状态(等待完成),不论是否有排队数据未发送或未被确认。这种关闭方式称为“强行关闭”,因为套接字的虚电路立即被复位,尚未发出的所有数据都会丢失。在远端的recv()调用都会失败,并返回WSAECONNRESET错误。
在connect成功建立连接之后设置该选项:
linger m_sLinger;
m_sLinger.l_onoff = 1; // (在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
m_sLinger.l_linger = 0; // (容许逗留的时间为0秒)
setsockopt(sockConnected,
SOL_SOCKET,
SO_LINGER,
(const char*)&m_sLinger,
sizeof(linger));
总结
也许我们避免不了CLOSE_WAIT状态冻结的再次出现,但我们会使影响降到最小,希望那个重用套接字选项能够使得下一次重新建立连接时可以把CLOSE_WAIT状态踢掉。
我的意思是:当一方关闭连接后,另外一方没有检测到,就导致了CLOSE_WAIT的出现,上次我的一个朋友也是这样,他写了一个客户端和 APACHE连接,当APACHE把连接断掉后,他没检测到,出现了CLOSE_WAIT,后来我叫他检测了这个地方,他添加了调用 closesocket的代码后,这个问题就消除了。
如果你在关闭连接前还是出现CLOSE_WAIT,建议你取消shutdown的调用,直接两边closesocket试试。
另外一个问题:
比如这样的一个例子:
当客户端登录上服务器后,发送身份验证的请求,服务器收到了数据,对客户端身份进行验证,发现密码错误,这时候服务器的一般做法应该是先发送一个密码错误的信息给客户端,然后把连接断掉。
如果把
m_sLinger.l_onoff = 1;
m_sLinger.l_linger = 0;
这样设置后,很多情况下,客户端根本就收不到密码错误的消息,连接就被断了。
出现CLOSE_WAIT的原因很简单,就是某一方在网络连接断开后,没有检测到这个错误,没有执行closesocket,导致了这个状态的实现,这在TCP/IP协议的状态变迁图上可以清楚看到。同时和这个相对应的还有一种叫TIME_WAIT的。
另外,把SOCKET的SO_LINGER设置为0秒拖延(也就是立即关闭)在很多时候是有害处的。
还有,把端口设置为可复用是一种不安全的网络编程方法。
能不能解释请看这里
http://www.bt285.cn BT下载
再看这个图:
http://www.5a520.cn 小说520网
断开连接的时候,
当发起主动关闭的左边这方发送一个FIN过去后,右边被动关闭的这方要回应一个ACK,这个ACK是TCP回应的,而不是应用程序发送的,此时,被动关闭的一方就处于CLOSE_WAIT状态了。如果此时被动关闭的这一方不再继续调用closesocket,那么他就不会发送接下来的FIN,导致自己老是处于CLOSE_WAIT。只有被动关闭的这一方调用了closesocket,才会发送一个FIN给主动关闭的这一方,同时也使得自己的状态变迁为LAST_ACK。
比如被动关闭的是客户端。。。
当对方调用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.
发表评论
-
推荐JS压缩工具ESC
2009-01-08 20:13 2110昨天将CheckBox转Text的代码从HTML中剥离出来之 ... -
怎样用Java来获取真实的IP地址
2009-01-06 13:05 7435在JSP里,获取客户端的IP地址的方法是:request.ge ... -
tcp相关状态
2008-12-16 14:42 1269客户端口实际上就是从本机访问其它计算机服务时打开的源端 ... -
网站前端优化一些小经验
2008-12-04 20:32 915着第3届bt论坛的顺利结 ... -
Base64基础(2)
2008-12-02 10:19 1290url: http://zh.wikipedia.org/wi ... -
什么是Base64以及sun.misc.BASE64Decoder的用法
2008-11-24 15:10 4806Base64是网络上最常见的用于传输8Bit字节代码的编码方式 ... -
Regex的一些常用例子
2008-11-11 12:37 1299import java.util.HashMap; imp ... -
值得收藏的健康知识
2008-11-03 11:53 1520不要死于无知。 不要拿 ... -
java的File#renameTo(File)方法的陷井
2008-10-27 10:17 1647以前我一直以为File#renameTo(File)方法与OS ... -
垂直搜索的信息分类如何做
2008-10-24 10:09 1451垂直搜索的优势就在 ... -
Twitter的增容处理
2008-10-21 12:00 962文/Patrick Joyce译/杨昊 由于之前 ... -
一步步图解 Tomcat 体系结构
2008-10-08 10:42 2249Apache Tomcat 是一款非常著名的开源 Servle ... -
Java编码原理与解决方案
2008-10-07 22:40 1276一、Java编码是怎么回事? 对于使用中文以及其他非拉丁语系语 ... -
JAVA分布式应用中使用XML数据
2008-09-24 15:14 1261可扩展标记语言(XML) ... -
红黑树(red-black tree)算法,附AVL树的比较
2008-09-03 15:01 14095红黑树的定义 正如在CLR ... -
状态对象:数据库的替代者
2008-09-03 10:39 880这是一个实战中非常重 ... -
一个计算机专业学生几年的编程经验汇总
2008-08-02 21:04 1380想来学习Java也有两个年头了,永远不敢说多么精通,但也想谈谈 ... -
UUID的介绍与使用
2008-07-30 17:24 2853一.UUID的介绍:UUID又称为通用唯一标识符,是一个128 ... -
htmlparser使用指南
2008-07-05 14:07 2984需要做一个垂直搜索引擎,比较了nekohtml和htmlp ... -
Apache安装配置与优化
2008-07-04 15:06 1621文针对apache web服务器的安装配置收集有效的一些经验 ...
相关推荐
关于系统端口出现CLOSE_WAIT状态的解决方案,讲解明确清晰,值得参考
close_wait_0306 close_wait_0306 close_wait_0306 close_wait_0306 close_wait_0306 close_wait_0306
CLOSE_WAIT 错误详解
详细描述TCP的各个状态,初学者可以快速理解掌握tcp状态图
tcp连接出现close_wait状态?
close_wait
对于服务器挂起中的CLOSE_WAIT & FIN_WAIT2 解决方案。
解决Close_Wait问题的相关资料。
1. 主动关闭连接的 - 也就是主动调socket的close操作的,最终 2. 被动关闭连接的,有个中间状态,即CLOSE_WAIT,因为协议 4. 在个连接
epoll机制epoll_create、epoll_ctl、epoll_wait、close(在epoll的ET模式下,read和write或send和recv当返回值0且errno=EAGAIN - linking530的专栏 - CSDN博客.mht
在内核级别,向应用程序发出关闭请求,并且CLOSE_WAIT的状态等待,并且连接保持超时。 使用命令netstat -p tcp -n | grep CLOSE_WAIT进行检查,如下所示。 tcp4 0 0 127.0.0.1.50937 127.0.0.1.8383 CLOSE_WAIT ...
导致客户TCP发送一个FIN给服务器,服务器则以一个ACK响应,此时服务器处于CLOSE_WAIT状态,客户端处于FIN_WAIT_2状态。服务器接收到FIN,子进程中止。子进程中止内核关闭所有子进程打开的描述符导致服务器向客户端...
Fix-Close_Hyper-V.bat
2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。 3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的...
boost变换器的闭环仿真模型,模型可正常运行,参数方便修改。
webmagic 最新包 修复protocol_version,Received close_notify during handshake
屏蔽ctrl+alt+delete
这是一个delphi的关闭屏幕保护程序的开发例子.
python利用urlopen下载网站数据,刚刚接触python,由于raw.githubusercontent.com服务器一直无法连接,故而将一个json文件上传csdn测试是否能下载。
fm_close_20150101_20201231.rar