如何使用winsock32处理多客户端

问题描述 投票:0回答:1

我正在学校学习通过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个以上的客户端提供服务。有人可以解决我的问题吗?非常感谢!

c++ sockets client-server winsock
1个回答
0
投票

您显示的一个线程可以处理4096。这是因为FD_SET被限制为4096个条目。但是,您可以有多个线程和多个FD_SET。

每个线程都有其FD_SET以读取和回复,最多可处理4k个客户端。当客户端4097到达时,您将创建一个新线程来处理一组新的套接字。您需要围绕接受和连接进行同步。但是除此之外,处理第一个4k的线程可以独立于处理接下来的4k客户端的线程运行。

完整示例超出范围。 :-)

© www.soinside.com 2019 - 2024. All rights reserved.