我正在製作一個可能需要處理3000多個連接的遊戲服務器(TCP)。 目前它有50個連接,我已經遇到滯後。Winsock發送呼叫很慢
我發現它的winsock send()調用每次需要100〜300ms才能返回,因爲它是單線程服務器,所以整個服務器的速度非常慢。
到目前爲止,我已經想到了兩種解決方案。
- 重新設計我的服務器,爲每個客戶端創建一個線程(爲3000個客戶端創建3000多個線程是否真的很穩定?)。
- 找到一種方法使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);
}
任何幫助將不勝感激。 謝謝。
這就是爲什麼遊戲使用UDP - 雖然UDP不能保證通過數據包接收。另外,您發送的數據有多大? – BugFinder 2012-07-19 13:15:12
您應該立即找到使發送呼叫立即返回的方法。對於服務器來說,3000個這樣的服務器將非常昂貴。我不知道關於winsock的具體內容,所以不會回答這個問題,但在C#中可以通過使用異步調用來完成。 – AlexDev 2012-07-19 13:16:01
遊戲服務器正在使用TCP作爲房間列表和重要數據包......這是我遇到瓶頸的地方。 我使用UDP作爲玩家動作的遊戲玩法等。 – user1537941 2012-07-19 13:57:05