我有一个C ++游戏服务器,我正在使用一个在Windows中使用winsock的网络库 。 我一直在对我的服务器进行压力测试,看看它一次可以接受多少个连接。当我使用我的游戏客户端进行连接时,它工作正常,但在我进行下面描述的压力测试后,我的游戏客户端无法再连接。
压力测试是,我使用一个简单的循环程序连接到我的服务器大约1000次,它只是启动与我的游戏服务器的tcp连接并立即关闭它。他们都连接起来。然后,之后,我尝试连接我的游戏。游戏根本没有连接。
我检查了库(见下文)中的tcpaccept()函数,没有输出。出于某种原因,在我对1000个连接的“攻击”之后,accept()停止接受连接。 什么可能使我的服务器停止接受连接?
这是我的循环摘要,它监听并接受连接并关闭它们:
function cube(n) {
return Math.pow(n, 3);
}
function compute(n) {
n = cube(n);
// return jQuery promise `n`: `cube(n)`
return $.when(n);
}
compute(5)
.done(function(data) {
console.log(data);
});
compute(2)
.done(function(data) {
console.log(data);
});
以下是 tcplisten,tcpaccept,CSocket :: CSocket(SOCKET),CSocket :: tcplisten(...)和CSocket :: tcpaccept(...)的定义:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
在1000次连接压力测试后,我该怎么做才能弄清楚为什么accept()不再接受连接?它与完成后关闭连接的方式有关吗?当我这样做时,我只是打电话: closesocket(sockID)。
请询问所需的任何其他代码!
修改 我刚刚注意到我的“压力测试” java程序在连接 668次后出现异常。这是例外:
bool serverIsOn = true; double listen = tcplisten(12345, 30000, 1); setnagle(listen, true); ... while(serverIsOn){ double playerSocket = tcpaccept(listen, 1); if(playerSocket > -1){ cout << "Got a new connection, socket ID: " << playerSocket << endl; //add their sockID to list here! addSockIDToList(playerSocket); } //Loop through list of socks and parse their messages here.. //If their message size == 0, we close their socket via closesocket(sockID); loopThroughSocketIdsAndCloseOnLeave(); } cout << "Finished!" << endl;
答案 0 :(得分:1)
因为您的服务器端正在关闭套接字,所以它们很可能在time_wait中待几分钟。 Windows具有控制最大套接字和各种状态的各种参数。我猜你的程序在几分钟后重新开始工作,并且可能在事件查看器中有一些警告。
另一种选择可能是在几分钟内忽略这些插座并希望它们消失。即当你根本不回应时客户端调用closesocket,这意味着你不会招致time_wait。这通常有效,但并非总是如此。如果他们不这样做,那么你在后台慢慢调用closesocket()。
如果您真的想要,也可以重置连接,请参阅TCP option SO_LINGER (zero) - when it's required了解详细信息,但重置连接并不正常,因此请务必阅读有关So_linger以及tcp拆解如何工作的广泛内容。
答案 1 :(得分:0)
事实证明这个库有它自己关闭套接字的方法:
int closesock(int sockid)
{
CSocket*sock = (CSocket*)sockets.item(sockid);
if(sock == NULL)return -1;
delete sock;
sockets.set((int)sockid, NULL);
return 1;
}
因此它通过套接字列表中的sockID获取当前套接字。 然后,如果sockID与有效套接字相关,则删除sock对象并在套接字列表中将其设置为NULL。
问题是我只是调用 closesocket(sockID)而不是 closesock(sockID),它执行关闭套接字所需的必要操作。
感谢大家的帮助。