我正在学校学习通过socket
使用Winsock
(C ++)建立客户端-服务器通信模型。我面临的问题是如何使服务器使用有限的资源为多客户端服务,而我的任务是使用多线程和探索技术来解决该问题,具体是在C ++和winSock中使用两个函数:select()
和_beginthreadex()
。 (对资源的假设有限)如果我仅使用select()
功能,那么我的服务器仅服务于最大的1024
客户端,如果我仅使用_beginthreadex()
,则它将在资源上受到限制。但是我需要为4096
以上的客户端提供服务,只需使用select()
和_beginthreadex()
(由于上述原因,不能仅使用其中之一)这是我的程序使用结构select()
:
SOCKET client[FD_SETSIZE], connSock;
fd_set readfds, initfds; //use initfds to initiate readfds at the begining of every loop step
sockaddr_in clientAddr;
int nEvents, clientAddrLen;
bool ret;
for (int i = 0; i < FD_SETSIZE; i++)
client[i] = 0; // 0 indicates available entry
FD_ZERO(&initfds);
//Step 5: Communicate with clients
while (1) {
FD_SET(listenSock, &initfds);
for (int i = 0; i < FD_SETSIZE; ++i) {
if (client[i] > 0) {
FD_SET(client[i], &initfds);
}
}
readfds = initfds; /* structure assignment */
nEvents = select(0, &readfds, 0, 0, 0);
if (nEvents < 0) {
printf("\nError! Cannot poll sockets: %d", WSAGetLastError());
break;
}
//new client connection
if (FD_ISSET(listenSock, &readfds)) {
clientAddrLen = sizeof(clientAddr);
if ((connSock = accept(listenSock, (sockaddr *)&clientAddr, &clientAddrLen)) < 0) {
printf("\nError! Cannot accept new connection: %d", WSAGetLastError());
break;
}
else {
printf("You got a connection from %s\n", inet_ntoa(clientAddr.sin_addr)); /* prints client's IP */
cout << "\tconnSocket: " << (int)connSock << endl;
int i;
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] == 0) {
client[i] = connSock;
FD_SET(client[i], &initfds);
break;
}
if (i == FD_SETSIZE) {
printf("\nToo many clients.");
closesocket(connSock);
}
if (--nEvents == 0)
continue; //no more event
}
}
//receive data from clients
for (int i = 0; i < FD_SETSIZE; i++) {
if (client[i] == 0)
continue;
if (FD_ISSET(client[i], &readfds)) {
ret = bussiness(client[i]); // the fuction handle logic of my server
if (ret == false ) {
FD_CLR(client[i], &initfds);
closesocket(client[i]);
client[i] = 0;
}
}
if (--nEvents <= 0)
continue; //no more event
}
}
//Step 5: Close socket
closesocket(listenSock);
使用以上程序,我的服务器不能为4096个以上的客户端提供服务。有人可以解决我的问题吗?非常感谢!
您显示的一个线程可以处理4096。这是因为FD_SET被限制为4096个条目。但是,您可以有多个线程和多个FD_SET。
每个线程都有其FD_SET以读取和回复,最多可处理4k个客户端。当客户端4097到达时,您将创建一个新线程来处理一组新的套接字。您需要围绕接受和连接进行同步。但是除此之外,处理第一个4k的线程可以独立于处理接下来的4k客户端的线程运行。
完整示例超出范围。 :-)