测试采用的是单机测试,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。
5
"及时清除不用的子线程。 Private Sub dogthread(ByVal Tzobj As System.Object, ByVal e As System.EventArgs) dogrunBZ(Tzobj) = True "正在运行时,防止重复运行 Try mySocket(Tzobj).Shutdown(SocketShutdown.Receive) "关闭套接字接收 "mySocket(Tzobj).Shutdown(SocketShutdown.Both) "组态王对此条支持不好 Catch End Try Try mySocket(Tzobj).Close() "引发子线程立即异常,中断子线程循环 Catch End Try Try myThread(Tzobj).Abort() "中止某个线程,销毁这些线程,需要很多时间! myThread(Tzobj).Join(300) "等待300毫秒,超时也终止,防止不出来 Catch End Try Try mySocket(Tzobj) = Nothing "防止组态王响应没那么快! Catch End Try GC.Collect() dogrunBZ(Tzobj) = False "运行完毕标志 End Sub
5
"及时清除不用的子线程。 Private Sub dogthread(ByVal Tzobj As System.Object, ByVal e As System.EventArgs) dogrunBZ(Tzobj) = True "正在运行时,防止重复运行 Try mySocket(Tzobj).Shutdown(SocketShutdown.Receive) "关闭套接字接收 "mySocket(Tzobj).Shutdown(SocketShutdown.Both) "组态王对此条支持不好 Catch End Try Try mySocket(Tzobj).Close() "引发子线程立即异常,中断子线程循环 Catch End Try Try myThread(Tzobj).Abort() "中止某个线程,销毁这些线程,需要很多时间! myThread(Tzobj).Join(300) "等待300毫秒,超时也终止,防止不出来 Catch End Try Try mySocket(Tzobj) = Nothing "防止组态王响应没那么快! Catch End Try GC.Collect() dogrunBZ(Tzobj) = False "运行完毕标志 End Sub
5
就是对方说”本人要关啦“,你说”哦,知道了“,万一”哦,知道了“这句话对方没听见呢,真的是个”可靠的“家伙吧,想得真”周到“
5
没看到你的测试的东西。没办法试。
return diantou.dataProxy.questionTopic.getLinkIds(id)
.getArray(value => diantou.dataProxy.question.get(value))
.getHash(value => value.bestAnswerId)
.getArray(value => diantou.dataProxy.answer.get(value))
.getFind(value => value != null)
这些是c# 新特性吧。看不懂。
1
这是 TCP 协议的问题哦,原因是它是一个“可靠的”家伙。
就是对方说”本人要关啦“,你说”哦,知道了“,万一”哦,知道了“这句话对方没听见呢,真的是个”可靠的“家伙吧,想得真”周到“TCP的可靠可不是这样子的,真要这样的话,双方永远都关不了了。
那是啥样的呢?所以等一会儿,哦,对方没有重复唠叨,那么本人也可以关了
10
那是啥样的呢?所以等一会儿,哦,对方没有重复唠叨,那么本人也可以关了
TCP的可靠仅仅是指,没有收到应答就重发。
现在的情况是客户端关闭,发出FIN,然后收到服务端回发的FIN,这种情况下客户端既不收也不发了,与可靠还有什么关系?
可以强制终止TCP的可靠性的。在不进行设置的情况下,close是会延时释放资源,并尝试把挂起在套接字上的数据或其他发送或接收。
下面是MSDN:
当 LingerState 属性更改 Close 方法的行为方式。 假如设置此属性,将修改 Winsock 可重置的连接的条件。 基于 IP 协议行为还是会出现连接重置。
当仍然要发送数据时,此属性控制面向连接的连接在对 Close 调用后仍保持打开的时间长度。
且LingerState的默认值是false,这时close后会“尝试发送挂起的数据,直到默认 IP 协议超时过期。”
详见:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.lingerstate.aspx
怎么样这也不能的话,那只能深入研究close方法的实现了
5
那是啥样的呢?所以等一会儿,哦,对方没有重复唠叨,那么本人也可以关了
TCP的可靠仅仅是指,没有收到应答就重发。
现在的情况是客户端关闭,发出FIN,然后收到服务端回发的FIN,这种情况下客户端既不收也不发了,与可靠还有什么关系?可以强制终止TCP的可靠性的。在不进行设置的情况下,close是会延时释放资源,并尝试把挂起在套接字上的数据或其他发送或接收。
下面是MSDN:
当 LingerState 属性更改 Close 方法的行为方式。 假如设置此属性,将修改 Winsock 可重置的连接的条件。 基于 IP 协议行为还是会出现连接重置。
当仍然要发送数据时,此属性控制面向连接的连接在对 Close 调用后仍保持打开的时间长度。
且LingerState的默认值是false,这时close后会“尝试发送挂起的数据,直到默认 IP 协议超时过期。”
详见:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.lingerstate.aspx
怎么样这也不能的话,那只能深入研究close方法的实现了
就是不知道没有挂起数据的时候会不会立即释放所占资源
5
200
5
5
为什么不试试做几个TCP数据转发器,来增加数据发送或接收端口呢和数据量呢,好像网上有这类工具下载呢
lz 需要在10几分钟内用1千万个端口(或等价的东西)。
1
1
不知道对不对,CMD命令行里不是有 taskkill/pid 端口号来清除端口号,你可以把这种功能用C #写出来。可以试试
然后可以做一个winform来实现这个清除端口号,应该可以的
1
那是啥样的呢?所以等一会儿,哦,对方没有重复唠叨,那么本人也可以关了
TCP的可靠仅仅是指,没有收到应答就重发。
现在的情况是客户端关闭,发出FIN,然后收到服务端回发的FIN,这种情况下客户端既不收也不发了,与可靠还有什么关系?
所以后面的兄弟给你回复的是对的 Linger 正是干这个的,你可以在 Close 时强行关闭,那么就是要放弃其可靠性,丢弃协议栈缓存数据,另外 FIN 与其 ACK 本身也需要可靠性