2014-03-01 75 views
0

我做了一個非常簡單的C++套接字服務器。每次新客戶端連接時,我都會嘗試創建一個線程(因此可以並行執行讀取操作)。C++ winsocket線程問題

void Server::start(void){ 
    for(;;){ 
     Logger::Log("Now accepting clients"); 
     int client; 
     struct sockaddr_in client_addr; 
     size_t addr_size = sizeof(client_addr); 
     client = accept(this->m_socket, (sockaddr*)&client_addr, 0); 
     if(client != SOCKET_ERROR){ 
      Logger::Log("New client connected!"); 
      StateObject client_object(client, this); 
      this->clients.push_back(&client_object); 

      std::stringstream stream; 
      stream<<this->clients.size()<<" clients online"; 
      Logger::Log(const_cast<char*>(stream.str().c_str())); 
      std::thread c_thread(std::bind(&StateObject::read, std::ref(client_object))); 
      //c_thread.join(); //if I join the child, new clients won't be accepted until the previous thread exits 
     } 
    } 
} 

閱讀方法在客戶端類:

void StateObject::read(){ 
    Logger::Log("Now reading"); 
    for(;;){ 
     int bytesReceived = recv(this->socket, buffer, 255, 0); 
     if(bytesReceived > 0){ 
      Logger::Log(const_cast<char*>(std::string("Received: " + std::string(buffer).substr(0, bytesReceived)).c_str())); 
     }else if(bytesReceived == 0){ 
      Logger::Log("Client gracefully disconnected"); 
      break; 
     }else{ 
      Logger::Log("Could not receive data from remote host"); 
      break; 
     } 
    } 
    Server * server = reinterpret_cast<Server*>(parent); 
    server->removeClient(this); 
} 

目前,客戶端連接後拋出一個異常: Screenshot

爲什麼以及何時已中止被觸發? 請注意,這是在子線程未加入主線程時發生的。在另一種情況下,「流量」預計會同步(當前客戶端線程必須退出,以便循環可以繼續接受下一個客戶端)。

注:

  • 因爲我綁到Windows,我無法派生子任務 - 我也不Cygwin的的粉絲。異步win32方法似乎使事情複雜化,這就是爲什麼我避免它們。
  • C++ std::thread reference
  • 測試已通過它超出範圍之前進行的Telnet
+1

你要麼需要分離的線程或加入它,它超出範圍之前..否則'的std :: thread'調用'的std :: terminate'在其析構函數。 – Brandon

+0

謝謝!我不知道它必須手動分離。請添加您的陳述作爲答案,以便我可以標記它。 – Gabe

回答