2016-11-15 117 views
-2

我想創建一個多線程套接字服務器。我有服務器工作正常,但是當我嘗試將我的代碼移入輔助函數時,服務器在讀取客戶端數據時停止工作。C++多線程套接字無法接收客戶端數據

原始代碼: main.cpp中

int sock; 

main(){ 
    SocketServer *ss = new SocketServer(8888); 
    pthread_t thread; 
    if(ss != NULL){ 
     while(true){    
      sock = ss->Accept(); 
      char* out; 
      ss->GetRequest(sock, out); 
     } 
    } 
} 

SocketServer.cpp

void SocketServer::GetRequest(int msgsock, char* out){ 
    char buf[1024]; 
    int rval; 
    std::cout<<"before read\n"; 
    if ((rval = read(msgsock, buf, 1024)) < 0){ 
     perror("reading socket"); 
    }else{ 
     strcpy(out,buf); 
    } 
    std::cout<<"after read\n"; 
} 

添加線程之後: main.cpp中

int sock; 

main(){ 
    SocketServer *ss = new SocketServer(8888); 
    pthread_t thread; 
    if(ss != NULL){ 
     while(true){    
      sock = ss->Accept();  
      pthread_create(&thread, NULL, SocketThread, &(*ss));  
      pthread_detach(thread);  
     } 
    } 
} 

static void* SocketThread(void* lp){  
    SocketServer *ss = (SocketServer*) lp; 
    char* out; 
    ss->GetRequest(sock, out); 
} 

原始輸出:
讀取之前
後讀取

新成果:
前閱讀

+1

這完全破碎了。如果同時收到兩個連接,您會怎麼看?只有一個'sock'全局變量。你認爲'out'指向哪裏,GetRequest'會寫入?你需要學習如何使用調試器。 –

+0

@SamVarshavchik我只包含與錯誤相關的代碼片段。 out和GetRequest正在寫回到main。如果需要,我可以上傳其他代碼。 – sauzke

+0

如果你不知道你的bug在哪裏,那麼你不知道這些「片段」是否相關。 C++並不那麼簡單。僅僅因爲某個程序崩潰或無法在某個特定的地方工作並不意味着這就是錯誤所在。根據顯示的代碼唯一可以確定的是在所示的代碼中存在多個基本的錯誤。 –

回答

1

這被打破:

if ((rval = read(msgsock, buf, 1024)) < 0){ 
    perror("reading socket"); 
}else{ 
    strcpy(out,buf); 

你忽略rval,除非它發出錯誤信號。它應該是:

if ((rval = read(msgsock, buf, 1024)) < 0){ 
    perror("reading socket"); 
else if (rval == 0) { 
    // peer closed the connection 
    close(msgsock); // or closesocket(), depending on your platform 
    break; 
}else{ 
    strncpy(out,buf,rval); 

,這也斷了:

sock = ss->Accept();  
pthread_create(&thread, NULL, SocketThread, &(*ss)); 

線程開始處理客戶端在偵聽套接字沒有興趣。它需要的是接受套接字sock,它需要以這樣的方式得到它,它不會在下次調用時被覆蓋。通常,sock是接受循環中的局部變量,並通過pthread_create()傳遞。

相關問題