平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

TCP Socket编程的几点肮脏的问题

1.有客户端开多线程对服务器进行连接断开压力测试,在连接接近4000次时,再也连接不上服务器,过了段时间后恢复正常,而后再出现,如此往复.使用Prcess Explorer查看System Idle Process发现大量的TIME_WAIT状态下的Socket.
解析如下:
TCP TIME-WAIT 延迟断开TCP 连接时,套接字对被置于一种称为TIME-WAIT 的状态。这样,新的连接不会使用相同的协议、源 IP 地址、目标 IP 地址、源端口和目标端口,直到经过足够长的时间后,确保任何可能被错误路由或延迟的段没有被异常传送。在RFC 793 中,将这种套接字对不被其它连接重新使用的时间长度指定为 2 个MSL(最大段生存时间的 2 倍)或 4 分钟。对于Windows NT 和Windows 2000 来说,这是默认设置。然而,在此默认设置下,某些网络应用程序在很短时间内执行多个出站连接,就可能会在端口收回前用完所有的可用端口。Windows NT 和Windows 2000 提供两种方法来控制这种情况。第一种方法是使用TcpTimedWaitDelay 注册表参数,改变该数值。对于 Windows NT 和Windows 2000,其值最低可设置为30 秒,这样在大多数情况下不会出现问题。每二种方法是使用 MaxUserPorts 注册表参数,来配置用户可访问的临时端口数(用作出站连 接的源端口)。默认情况下,当应用程序从系统请求任何套接字用于出站调用时,就会提供一个数值在1024 到 5000 之间的端口。MaxUserPorts 参数可用于设置管理员所允许的出站连接的最大端口值。例如,将该值设置为10,000(十进制),就会有约 9000 个用户端口可用于出站连接。关于这一概念的详细信息,请参见 RFC 793,也可参见MaxFreeTcbs 和 MaxHashTableSize 注册表参数。
注册表位置:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
主动断开的一方进入TIME_WAIT状态,被动断开的一方进入CLOSE_WAIT状态.不要试图使用SO_DONTLINGER设置避免TIME_WAIT状态!!!

On a busy HTTP server, the number of sockets in this TIME_WAIT state can far exceed those in the ESTABLISHED state. For instance, I checked an IIS 6.0 box that serves a fairly busy corporate site earlier today and got 124 ESTABLISHED connections versus 431 in TIME_WAIT.

The side shutting down the connection gets the TIME_WAIT. It's typical for a webserver to shutdown the connection immediately after sending a response. If you can instead stash the connection away and give the client time to close it you can push the TIME_WAIT to them. I believe Apache does something like this. In the worst case, if the client doesn't shutdown the connection, say within 5 seconds, you'll have to do it and suffer the TIME_WAIT. However if in that time the client does initiate the close then you have avoided a TIME_WAIT.

2. If you are using I/O completion ports, note that the order of calls made to WSASend/WSARecv is also the order in which the buffers are populated. WSASend//WSARecv  should not be called on the same socket simultaneously from different threads, since it can result in an unpredictable buffer order.

3.作客户端开1024个稳定连接到服务器,然后使用Prcess Explorer强行非法关闭该客户端,1024个连接瞬间被异常断开,服务器将不能检测到所有socket的断开,如果是完成端口,即时当前打开KeepAlive,即时当前正在执行异步WSARecv, GetQueuedCompletionStatus仍然可能无法返回正确的错误提示客户端关闭! Socket资源将残留.原来我以为仅在瞬间断电,操作系统崩溃,网线拔开这3种情况下才会发生该现象,看来进程崩溃也可以导致,只是以前的socket数量不足以让操作系统来不及处理.
 
References:
Windows 2000 TCP/IP 实现详述
http://www.port80software.com/200ok/archive/2004/12/07/205.aspx
http://support.microsoft.com/kb/q196271/

posted on 2007-01-07 11:27 linghuye 阅读(7528) 评论(10)  编辑 收藏 引用 所属分类: 编程札记

评论

# re: TCP Socket编程的几点问题  回复  更多评论   

网络部分是你自己写的?没用现成的库比如Raknet、Boost.Asio?它们测试并发连接都能达到上万。







2007-01-07 14:59 | countzero

# re: TCP Socket编程的几点问题  回复  更多评论   

为什么windows要限制端口为5000以下?
端口为16位数,可以达到65535个的啊?
留下那些做何用?
2007-01-07 18:14 | 游子

# re: TCP Socket编程的几点肮脏的问题  回复  更多评论   

我的代码出现了大量的CLOSE_WAIT状态,不知道有没有什么办法解决?
2008-01-27 11:56 | 网络监控

# re: TCP Socket编程的几点肮脏的问题  回复  更多评论   

你可以设定等的时间为0,这样就不会出现close_wait啦
2008-06-06 16:57 | **

# re: TCP Socket编程的几点肮脏的问题  回复  更多评论   

It is cool that people can take the <a href="http://lowest-rate-loans.com/topics/business-loans">business loans</a> moreover, it opens up completely new opportunities.
2010-06-06 00:00 | Wallace30Patrice

# Great common sense here. Wish I’d tohuhgt of that.  回复  更多评论   

Great common sense here. Wish I’d tohuhgt of that.
2011-05-23 00:57 | Kacy
只有注册用户登录后才能发表评论。