gpt4 book ai didi

C++ WINSOCK tcpaccept 在 "attack"之后停止接受连接

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:18:12 26 4
gpt4 key购买 nike

我有一个用 C++ 编写的游戏服务器,我正在使用一个网络库在 Windows 中使用 winsock。我一直在对我的服务器进行压力测试,看看它一次可以接受多少个连接。当我使用我的游戏客户端连接时它工作正常,但在我进行如下所述的压力测试后我的游戏客户端无法再连接。

压力测试是,我使用一个简单的循环程序连接到我的服务器大约 1000 次,该循环只启动与我的游戏服务器的 tcp 连接并立即关闭它。他们都联系在一起。然后,之后,我尝试连接我的游戏。游戏根本无法连接。

我检查了库中的 tcpaccept() 函数(见下文),没有输出。出于某种原因,accept() 在我“攻击”了 1000 个连接后停止接受连接。什么可能会使我的服务器停止接受连接?

这是我对监听和接受连接并关闭它们的循环的总结:

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;

这是 tcplisten、tcpaccept、CSocket::CSocket(SOCKET)、CSocket::tcplisten(...) 和 CSocket::tcpaccept(...) 的定义:

double tcplisten(int port, int max, int mode)
{
CSocket* sock = new CSocket();
if(sock->tcplisten(port, max, mode))
return AddSocket(sock);
delete sock;
return -1;
}

double tcpaccept(int sockid, int mode)
{
CSocket*sock = (CSocket*)sockets.item(sockid);
if(sock == NULL)return -1;
CSocket*sock2 = sock->tcpaccept(mode);
if(sock2 != NULL)return AddSocket(sock2);
return -1;
}

...

CSocket::CSocket(SOCKET sock)
{
sockid = sock;
udp = false;
format = 0;
}

bool CSocket::tcplisten(int port, int max, int mode)
{
if((sockid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return false;
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
if(mode)setsync(1);
if(bind(sockid, (LPSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
closesocket(sockid);
return false;
}
if(listen(sockid, max) == SOCKET_ERROR)
{
closesocket(sockid);
sockid = INVALID_SOCKET;
return false;
}
return true;
}


CSocket* CSocket::tcpaccept(int mode)
{
if(sockid == INVALID_SOCKET) return NULL;
SOCKET sock2;
if((sock2 = accept(sockid, (SOCKADDR *)&SenderAddr, &SenderAddrSize)) != INVALID_SOCKET)
{
//This does NOT get output after that 1000-'attack' test.
std::cout << "Accepted new connection!" << std::endl;
CSocket*sockit = new CSocket(sock2);
if(mode >=1)sockit->setsync(1);
return sockit;
}

return NULL;
}

在我的 1000 次连接压力测试后,我该怎么做才能弄清楚为什么 accept() 不再接受连接?这与我在完成连接后关闭连接的方式有关吗?当我这样做时,我所做的只是调用:closesocket(sockID)

请询问任何其他需要的代码!

编辑:我刚刚注意到我的“压力测试”java 程序 在连接了大约 668 次 后出现异常。这是异常(exception)情况:

Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at sockettest.SocketTest.main(SocketTest.java:63)
Java Result: 1

最佳答案

因为您的服务器端正在关闭套接字,它们很可能会在 time_wait 中等待几分钟。 Windows 有各种参数控制最大套接字和各种状态。我猜您的程序会在几分钟后重新开始运行,并且事件查看器中可能会出现一些警告。

另一种方法可能是简单地忽略这些套接字几分钟,并希望它们消失。也就是说,当您根本不响应时,客户端会调用 closesocket,这意味着您不会招致 time_wait。这通常有效,但并非总是如此。如果他们不这样做,那么您将在后台缓慢地对他们调用 closesocket()。

如果你真的想要,你可以重置连接,参见 TCP option SO_LINGER (zero) - when it's required有关详细信息,但重置连接是不正常的,因此一定要广泛阅读有关 So_linger 以及 tcp teardown 的工作原理。

关于C++ WINSOCK tcpaccept 在 "attack"之后停止接受连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30417144/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com