C++中的Winsock服务器在三个客户端后拒绝连接 [英] Winsock Server in C++ Refusing Connections After Three Clients

查看:37
本文介绍了C++中的Winsock服务器在三个客户端后拒绝连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 C++ 编写一个 Winsock 服务器,它从模数转换器收集数据并运行一个服务器,以便客户端可以登录并请求数据.我目前至少运行三个线程(主线程、模拟输入线程和服务器线程),而且服务器为每个连接的客户端分拆一个新线程.我现在正在测试代码,它接受来自客户端的连接三次,但在第四次尝试时拒绝连接.这是我用来接收连接并为每个客户端分离线程的 while 循环.当服务器拒绝连接时,它仍然在这个循环中.我从一些调试 printf 语句中知道.

I'm writing a Winsock server in C++ that collects data from a analog-to-digital converter and runs a server so that clients can log in and request the data. I currently have it running at least three threads (main thread, analog input thread, and a server thread), plus the server spins off a new thread for each connected client. I'm testing the code now and it accepts connections from a client three times, but refuses connection on the fourth attempt. This is the while loop I'm using to receive connections and spin off threads for each client. When the server is refusing connections, it's still in this loop. I know from some debugging printf statements.

while (serverActive) {
        //Accept client sockets as long as the server remains active
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ListenSocket == INVALID_SOCKET) {
            printf("Accept failed");
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
        std::thread clientThr(clientHandlerThread, ClientSocket);
        clientThr.detach();
    }

这是客户端处理程序线程的代码.中间的所有 if-elseif-else 语句只是我为与客户端通信而设置的协议.我正在使用的测试程序客户端代码从客户端关闭套接字.我阅读了其他一些帖子,其中说这有时是问题所在,但在这种情况下似乎不是问题.有什么想法吗?

This is the code for the client handler thread. All the if-elseif-else statements in the middle are just the protocol I'm setting up to communicate with clients. The tester client code I'm using closes the socket from the client side. I read some other postings where it said this is sometimes the problem, but it doesn't seem to be the problem in this case. Any thoughts?

int clientHandlerThread(SOCKET client) {
    int iResult, iSendResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;

    char  * p_m6 = reinterpret_cast< char  *>(&data_ai_SC1Mod6[0]);
    char  * p_m7 = reinterpret_cast< char  *>(&data_ai_SC1Mod7[0]);
    char  * p_m8 = reinterpret_cast< char  *>(&data_ai_SC1Mod8[0]);

    //Receive data until the client closes the connection
    do {
        iResult = recv(client, recvbuf, recvbuflen, 0);
        if (iResult > 0) {
            recvbuf[iResult] = (char)0;
            printf("Received Command: ");
            printf(recvbuf);
            printf("\n");

            if (recvbuf[4] == 'V') {
                if (recvbuf[6] == '6') {
                    iSendResult = send(client, "SCXI>", 5, 0);
                    iSendResult = send(client, p_m6, 64, 0);
                    iSendResult = send(client, "<SCXI", 5, 0);
                }
                else if (recvbuf[6] == '7') {
                    iSendResult = send(client, "SCXI>", 5, 0);
                    iSendResult = send(client, p_m7, 64, 0);
                    iSendResult = send(client, "<SCXI", 5, 0);
                }
                else if (recvbuf[6] == '8') {
                    iSendResult = send(client, "SCXI>", 5, 0);
                    iSendResult = send(client, p_m8, 64, 0);
                    iSendResult = send(client, "<SCXI", 5, 0);
                }
                else {
                    iSendResult = send(client, "SCXI>Unrecognized Module<SCXI", 29, 0);
                }
            }
            else {
                iSendResult = send(client, "SCXI>Unrecognized Command<SCXI", 30, 0);
            }
            if (iSendResult == SOCKET_ERROR) {
                printf("Send failed");
                closesocket(client);
                WSACleanup();
                return 1;
            }
        }
        else {
            closesocket(client);
            WSACleanup();
            return 1;
        }
    } while (iResult > 0);

    closesocket(client);
    WSACleanup();
    return 0;
}

推荐答案

它在第一个连接线程退出后开始拒绝连接,因为您在线程中错误地调用了 WSACleanup().去掉它.您还应该将其从接受循环中删除.您应该只在准备退出整个过程时调用它.

It starts refusing connections after the first connect thread exits, because you're incorrectly calling WSACleanup() in the thread. Remove it. You should also remove it from the accept loop. You should only call it when you are ready to exit the entire process.

注意,您在接受循环中测试了错误的套接字.

NB you're testing the wrong socket in the accept loop.

注意 2 您的代码做出了一个站不住脚的假设,即每个 recv() 都会收到一条完整的消息.

NB 2 Your code makes the untenable assumption that every recv() receives one entire single message.

这篇关于C++中的Winsock服务器在三个客户端后拒绝连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆