2012-12-26 61 views
1

我有下面的代碼,我不知道爲什麼不能正常工作。接受電話不會第二次(或不止一次)阻止?

它是循環接受()調用,每次觸發指定

線程多線程TCP服務器。

的問題是,接受有時不會塊,從而導致

程序打開一個新的線程時,有理論上沒有關係。

這就是循環 -

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; 

當我通過瀏覽器連接到服務器時出現問題,

例如,

第一個線程完成後(I`通過臨時睡眠主線程5秒鐘來確定)

它清理所有內容並關閉客戶端套接字,

雖然在第二接受電話 - 它會用相同的

SOCKADDR信息返回,並導致額外的線程上去,

接收完全相同的數據,發送數據完全相同。

和印刷2(有時甚至更多)時間:

「服務器性反應的消息已發送。」

我無法弄清楚爲什麼會發生這種情況,希望你們能幫助我。

謝謝!

回答

0

這是一個有點猜測,但我在這行代碼感到奇怪的邏輯:

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

它期待AcceptConnection當它成功返回一個非零值和零值時它失敗。但是,該函數成功時會返回一個常量SUCCESS。但是,某些Windows頭文件將常數SUCCESS定義爲0.並且各種失敗常量是一些非零值。

即使你定義在自己的代碼的成功和失敗,它可能是有意義的專門檢查返回值,例如:

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

Hello Mark, 感謝您的評論! 這確實有點令人費解,難以理解,我會改變它。 我的確將它們自己定義爲(SUCCESS 1; FAILURE 0) 並在整個解決方案中使用它們。 雖然調試表明這不是問題不幸, ,我不知道它的來源是什麼。 –

0

一個可能的問題:它看起來並不像你設置clients[dwI].bIsInUse在分配新的客戶端SOCKET之後爲true,這會在for循環中弄亂你的邏輯。