gpt4 book ai didi

c++ - Winsock 发送调用很慢

转载 作者:行者123 更新时间:2023-11-30 02:03:39 25 4
gpt4 key购买 nike

我正在制作一个可能需要处理 3000 多个连接的游戏服务器 (TCP)。目前它有 50 个连接,我已经遇到了延迟。

我发现它的 winsock send() 调用每次返回大约需要 100 ~ 300 毫秒,这大大降低了整个服务器的速度,因为它是一个单线程服务器。

到目前为止,我想到了两种解决方案。

  1. 重新设计我的服务器,为每个客户端创建一个线程(为 3000 个客户端创建 3000 多个线程真的稳定吗?)。
  2. 想办法让 send() 调用立即返回。

这是我的套接字初始化代码:

int ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if(ret != 0)
{
printf("Winsock failed to start.\n");
system("pause");
return;
}

server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(52000);

sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == INVALID_SOCKET)
{
printf("Invalid Socket.\n");
system("pause");
return;
}

if(bind(sock, (sockaddr*)&server, sizeof(server)) != 0)
{
printf("error");
return;
}

if(listen(sock, 5) != 0)
{
printf("error");
return;
}

在单独的线程中接受代码

sockaddr_in from;
int fromlen = sizeof(from);
SOCKET sTmpSocket = accept(ServerSock, (struct sockaddr*)&from, &fromlen);

我的发送函数

void CClient::SendPacket(BYTE* pPacket, DWORD Len)
{
DWORD ToSendLen = Len;
while (ToSendLen)
{
int iResult = send(this->ClientSocket, (char*)(pPacket + Len - ToSendLen), ToSendLen, 0);

if (iResult == SOCKET_ERROR)
return;

ToSendLen -= iResult;
}
}

这是我的服务器线程(不完整,只有相关部分)

while (1)
{
for (int i = 0; i < MAX_CLIENT; i++)
{
if (Clients[i].bConnected == false)
continue;

timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1;
fd_set socketset;
socketset.fd_count = 1;
socketset.fd_array[0] = Clients[i].ClientSocket;
if (select(0, &socketset, 0, 0, &timeout))
{
int RecvLen = recv(Clients[i].ClientSocket, (char*)pBuffer, 10000, MSG_PEEK);
if (RecvLen == SOCKET_ERROR)
{
Clients[i].bConnected = false;
iNumClients--;
}
else if (RecvLen == 0)
{
Clients[i].bConnected = false;
iNumClients--;
}
else if (RecvLen > 0)
{
// Packet handling here
recv(Clients[i].ClientSocket, (char*)pBuffer, dwDataLen, MSG_WAITALL);

//...
}
}
}

Sleep(1);
}

如有任何帮助,我们将不胜感激。谢谢。

最佳答案

我会选择 IOCP ( IO completion ports ) 可以带来所需的性能并且可以很好地扩展。看看Boost.Asio正在使用 IOCP在引擎盖下(在 Windows 上)。

拥有 3000 个或更多线程的想法非常糟糕,而且确实无法扩展(在内存消耗和上下文切换方面)!

关于c++ - Winsock 发送调用很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11561577/

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