【问题标题】:Accept call does'nt block the second time (or more than one time)?接受呼叫不会阻塞第二次(或不止一次)?
【发布时间】:2012-12-26 23:53:35
【问题描述】:

我有以下代码,但我不知道为什么它不能正常工作。

它是一个多线程 TCP 服务器,循环 accept() 调用并触发指定

每次线程。

问题是接受有时不会阻塞,从而导致

理论上没有连接时打开新线程的程序。

这就是循环 -

    for (dwI = 0;; dwI++)                       //Accept MAX_CLIENTS connections
{
    if(MAX_CLIENTS == dwI)
    {
        dwI=0;
        continue;
    }//if

    if(clients[dwI].bIsInUse)
    {
        continue;
    }//if

    ZeroMemory(&from,sizeof(from));

    if(!AcceptConnection(&ServerSock,&from,&ClientSock))
    {
        PRINT_LE("AcceptConnection",ERROR_ACCEPT_SERVER_CONNECTION);
        closesocket(ServerSock);
        WSACleanup();
        return EXIT_FAILURE;
    }//if

    clients[dwI].ClientSock = ClientSock;

    if(! (clients[dwI].hThread = CreateThread(
            NULL,               //Not inheritable
            0,                  //Default stack size
            ThreadedAcceptTCP,       //ThreadedAccept - function
            &clients[dwI],//Pass pointer to the socket
            0,                  //Start immidiately
            &clients[dwI].dwThreadId                //Save thread id
            )))
    {
        PRINT_GLE("CreateThread");
        closesocket(ServerSock);
        WSACleanup();
        return EXIT_FAILURE;
    }//if

    #ifdef PRINT_STATUS                     //Print status if macro is defined
        printf("Server responce message has been sent.\n");
    #endif
}//for

每个函数都有我自己的包装器。

AcceptConnection 的代码如下 -

    SOCKET ClientSocket = INVALID_SOCKET;       //Client socket
INT sockaddrSize = sizeof(*pSockAddr);

ClientSocket = accept(          //Create client accepting socket
                *pSock,         //Listen-ed socket
                pSockAddr,      
                &sockaddrSize   
                );

if (INVALID_SOCKET == ClientSocket)     //Check for errors - if any - cleanup and return failure
{
    PRINT_WSAGLE("socket");
    return FAILURE;
}//if

*pClientSock = ClientSocket;        //Pass socket

return SUCCESS;

当我通过浏览器连接到服务器时出现问题,

例如,

在第一个线程完成后(我已经通过暂时休眠主线程 5 秒来确保这一点)

它会清理所有内容并关闭客户端套接字,

虽然在第二次接受调用时 - 它会以相同的方式返回

SOCKADDR 信息并导致一个额外的线程上去,

接收完全相同的数据,发送完全相同的数据。

并打印 2 次(有时甚至更多):

“服务器响应消息已发送。”

我不明白为什么会发生这种情况,希望你们能帮助我。

谢谢!

【问题讨论】:

    标签: c winapi winsock winsock2 winsockets


    【解决方案1】:

    这有点猜想,但我想知道这行代码的逻辑:

    if(!AcceptConnection(&ServerSock,&from,&ClientSock))
    

    它期望AcceptConnection 在成功时返回一个非零值,在失败时返回一个零值。但是,该函数在成功时返回一个常量SUCCESS。但是,一些Windows头文件将常量SUCCESS定义为0。而各种失败的常量都是一些非零值。

    即使您在自己的代码中定义了 SUCCESS 和 FAILURE,也可能需要专门检查返回值,例如:

    if (FAILURE == AcceptConnection(&ServerSock,&from,&ClientSock))
    

    【讨论】:

    • 你好马克,谢谢你的评论!这确实有点令人费解和难以理解,我会改变它。事实上,我自己将它们定义为 (SUCCESS 1 ; FAILURE 0) 并在整个解决方案中使用它们。虽然调试表明这不是问题,但我不知道它的来源。
    【解决方案2】:

    一个可能的问题:在分配一个新的客户端 SOCKET 后,您似乎没有将 clients[dwI].bIsInUse 设置为 true,这会弄乱您的 for 循环中的逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多