TCP客户端Socket如何立即释放端口?
|
admin
2017年4月12日 1:29
本文热度 26881
|
在做一个关于web负载均衡的压力测试的时候碰到一个问题。测试采用的是单机测试,web服务器+3个负载均衡节点服务+客户端 都在同一台4核工作机上。由于测试逻辑简单,1024个http客户端4s左右会吃光6W个端口,继续访问就会出现错误:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。错误的原因是Socket占用的端口没有被释放,需要等待20+s才能进行下一轮测试,很浪费时间。需要说明的是,释放客户端端口不像服务器端口那样关闭Socket就可以了。客户端端口在Socket关闭之后处于Close_Wait状态,这个状态时间应该是由HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下的TcpTimedWaitDelay键值决定的,但是这个值最小值是30s。另外可以使用API函数SetTcpEntry强行关闭连接释放端口,但是某些操作系统由于UAC的原因需要提升为管理员权限,如果通过app.manifest设置管理员身份运行,会弹出一个提升权限的对话框,作为一个性能测试的Demo弹出这样一个框感觉有点吓人。希望高人指点,如何在不需要用户参与的情况下把端口释放掉。需要具体测试代码的话可以到这里下载https://fastcsharp.codeplex.com/,测试项目为demo.loadBalancingTcpCommandWeb。
该文章在 2017/4/12 1:29:55 编辑过
| |
全部评论5 |
|
admin
2017年4月12日 1:30
发现连接数超某数时,及时清除不用套接字子线程,服务器与客户端均可设超时强制关闭1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Private Sub dogthread( ByVal Tzobj As System. Object , ByVal e As System.EventArgs)
dogrunBZ(Tzobj) = True
Try
mySocket(Tzobj).Shutdown(SocketShutdown.Receive)
Catch
End Try
Try
mySocket(Tzobj).Close()
Catch
End Try
Try
myThread(Tzobj).Abort()
myThread(Tzobj).Join(300)
Catch
End Try
Try
mySocket(Tzobj) = Nothing
Catch
End Try
GC.Collect()
dogrunBZ(Tzobj) = False
End Sub
|
该评论在 2017/4/12 1:30:48 编辑过
|
|
admin
2017年4月12日 1:31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Private Sub dogthread( ByVal Tzobj As System. Object , ByVal e As System.EventArgs)
dogrunBZ(Tzobj) = True
Try
mySocket(Tzobj).Shutdown(SocketShutdown.Receive)
Catch
End Try
Try
mySocket(Tzobj).Close()
Catch
End Try
Try
myThread(Tzobj).Abort()
myThread(Tzobj).Join(300)
Catch
End Try
Try
mySocket(Tzobj) = Nothing
Catch
End Try
GC.Collect()
dogrunBZ(Tzobj) = False
End Sub
|
该评论在 2017/4/12 1:31:21 编辑过
|
|
admin
2017年4月12日 1:31
谢谢回复,真不是这么简单的事。你可以试试能不能在30s之内创建>65536个客户端连接。 该评论在 2017/4/12 1:31:56 编辑过
|
|
admin
2017年4月12日 1:32
我对tcp研究的不是那么深.. 请问你这个6W多连接 是长连接没有断开的?
不是吧 client的端口也没这么多..
如果是ope send close dispose的话 感觉还差不多可以..
否则这也不叫长连接了啊.....
难道你的意思 本地client使用了5000端口连接 然后这5000还可以个下一个client用?
不存在啊..那么你2个client 服务器如何找到客户端... 该评论在 2017/4/12 1:32:27 编辑过
|
|
admin
2017年4月12日 1:33
1 2 3 4 5 6 | TcpClient c = new TcpClient();
c.Connect(IPAddress.Parse( "x" ), o);
c.Client.Send(by);
c.Client.Shutdown(SocketShutdown.Both);
c.Client.Close();
c.Close();
|
这虽然是tcp_client但是发了就没了.....具体我还真没测试过..不知道我想的是不是跟你想的一样.. 该评论在 2017/4/12 1:33:04 编辑过
|