2016-08-19 80 views
-2
#include "create.h" 

std::mutex acceptMutex; 

namespace kojang{ 

    CreateServer::CreateServer() 
    { 
     init(); 
    } 

    void CreateServer::showError(const char * msg) 
    { 
     std::cout << "에러 : " << msg << std::endl; 
     exit(-1); 
    } 

    void CreateServer::init() 
    { 

     WSAStartup(MAKEWORD(2, 2), &wsa); 

     server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

     if (server == INVALID_SOCKET) 
      showError("서버 생성 실패"); 



     addr.sin_family = AF_INET; 
     addr.sin_addr.s_addr = inet_addr("192.168.0.2"); 
     addr.sin_port = htons(23000); 

     if (bind(server, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) 
      showError("바인딩 실패"); 

     if (listen(server, SOMAXCONN) == SOCKET_ERROR) 
      showError("듣기 실패"); 
    } 


    void CreateServer::Accept() 
    { 
     while (true) 
     { 
      std::cout << "클라이언트 접속 대기중.... " << std::endl; 
      c_size = sizeof(c_addr); 

      acceptMutex.lock(); 

      client = accept(server, (SOCKADDR*)&c_addr, &c_size); 
      if (client == INVALID_SOCKET) 
      { 
       std::cerr << "error" << std::endl; 
       acceptMutex.unlock(); 
       continue; 
      } 

      v.emplace_back(client); 

      acceptMutex.unlock(); 

      std::thread t1 = std::thread([this]{ this->run_r(&client);}); 
      t1.detach(); 
     } 
    } 


    void CreateServer::run_r(void* client) 
    { 
      rcv_msg(client); 
    } 


    void CreateServer::rcv_msg(void* data) 
    { 
     SOCKET* cl = (SOCKET*)data; 
     int len; 
     char message[500]; 

     while ((len = recv(*cl, message, sizeof(message) - 1, 0)) != -1) 
     { 
      std::cout << len <<" byte" << std::endl; 
      std::for_each(v.begin(), v.end(), [&len, &message, &cl](SOCKET sock){ send(sock, message, len, 0); }); 
     } 

    } 
} 
當客戶端連接服務器 但如果3客戶端connnect服務器,最後一個客戶端的線程運行良好,但第一

線程將被創建,第二個客戶端的線程沒有運行;我學習C++服務器編程,但是線程不工作

+0

很難說什麼是這些少數的代碼段會錯。您可能應該使用某些日誌記錄工具來增強您的代碼 –

+0

'client = accept(...' - 'client'不存在就我們所關心的。發佈一個[minimal。** complete **,可驗證的示例](https://stackoverflow.com/help/mcve),它會產生* real *問題,猜測是所有的線程都在同一個套接字hande * variable *上敲擊,這個套接字被每個啓動的新線程覆蓋。 – WhozCraig

回答

0

你傳遞一個指向同一個插座(&client)的所有線程,因此所有線程都使用同一個。

您應該改爲client

std::thread t1 = std::thread([this]{ this->run_r((void*)client);}); 

// ... 

void CreateServer::rcv_msg(void* data) 
{ 
    SOCKET cl = (SOCKET)data; 
    int len; 
    char message[500]; 

    while ((len = recv(cl, message, sizeof(message) - 1, 0)) != -1) 

    // ... 
0
void CreateServer::Accept() 
{ 
    while (true) 
    { 
     std::cout << "클라이언트 접속 대기중.... " << std::endl; 
     c_size = sizeof(c_addr); 

     acceptMutex.lock(); 

     SOCKET client = accept(server, (SOCKADDR*)&c_addr, &c_size); 
     if (client == INVALID_SOCKET) 
     { 
      std::cerr << "error" << std::endl; 
      acceptMutex.unlock(); 
      continue; 
     } 

     v.emplace_back(client); 

     acceptMutex.unlock(); 

     std::thread t1 = std::thread([this,client]{ this->run_r((void*)&client);}); 
     t1.detach(); 
    } 
} 

我只是改變我的代碼,這樣 謝謝大家 我用同一個插座在不同的線程