сокеты — (WINSOCK) C ++ Game Server: слишком много TCP-подключений одновременно на TCPAccept

Я пытаюсь провести стресс-тест на случай, если злоумышленники попытаются одновременно выполнить множество TCP-подключений к моему игровому серверу C ++.

Я сделал простую программу, которая 1000 раз соединяется через порт TCP
на мой игровой сервер. Вот где мой сервер принимает соединения:

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;

std::string ip = tcpip(playerSocket);
if(ipIsBanned(ip))
closesocket(playerSocket);
}
}

Вот определения tcplisten и tcpaccept:

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

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

Эта проблема: Сервер прекращает принимать соединения после завершения моей тестовой программы. Например, если я подключаюсь к своей игре после (которая запрашивает только одно подключение в отличие от моей программы тестовой атаки, которая запрашивает 1000 подключений), игра даже не сможет подключиться. Я также не вижу больше соединений через консольный вывод на моем сервере больше. Последнее соединение было сделано из программы атаки. Как будто он больше не может принять, и что-то сломалось, но я не могу понять, что, без исключений или ошибок.

Это огромная проблема для моего сервера, так как любой может легко просто аварийно завершить работу сервера и заставить его перезапустить, чтобы снова начать принимать новые подключения.

Что я могу сделать, чтобы бороться с этим? Я имею в виду, что я пытался даже установить максимальное количество соединений одновременно на 30 000, но это не сработало. Даже если это сработало, кто-то мог просто попытаться подключиться более 30000 раз, делая это бесполезным.

РЕДАКТИРОВАТЬ:

Более подробные определения функций tcplisten и tcpaccept выше:

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);
//TEMP ADD
sockid = INVALID_SOCKET;
return false;
}
return true;
}CSocket* CSocket::tcpaccept(int mode)
{
//TEMP REMOVE: if(sockid<0)return NULL;
if(sockid == INVALID_SOCKET) return NULL;
SOCKET sock2;
if((sock2 = accept(sockid, (SOCKADDR *)&SenderAddr, &SenderAddrSize)) != INVALID_SOCKET)
{
CSocket*sockit = new CSocket(sock2);
if(mode >=1)sockit->setsync(1);
return sockit;
}

return NULL;
}

РЕДАКТИРОВАТЬ 2:
Вот определение AddSocket:

int AddSocket(CSocket*b)
{
for(int i = 0; i < sockets.count; i ++)
{
if(sockets[i] == NULL)
{
sockets.set(i, b);
return i;
}
}
sockets.Add(b);
return sockets.count-1;
}

1

Решение

Если вы работаете в Linux, вы можете использовать tcp_tw_reuse Sysctl.

0

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector