2016-11-15 6 views
-2

マルチスレッドソケットサーバーを作成したいと思います。サーバーはうまく動作していますが、コードをワーカー関数に移動しようとすると、クライアントデータを読み取るときにサーバーが機能しなくなります。C++マルチスレッドソケットはクライアントデータを受信できません

オリジナルコード: 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); 
} 

オリジナル出力:リード前
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"; 
} 

スレッドを追加した後

新しい出力読んだ後:

+1

これは完全に壊れています。 2つの接続が同時に受信された場合、どうなると思いますか? 'sock'グローバル変数は1つしかありません。そして 'out'が指し示しているところは、' GetRequest'が書いてくれると思いますか?デバッガの使い方を学ぶ必要があります。 –

+0

@SamVarshavchikエラーに関連するコードのスニペットしか含まれていません。 outとGetRequestはmainに書き戻しています。必要に応じて他のコードをアップロードできます。 – sauzke

+0

あなたのバグの場所がわからない場合、これらのスニペットが適切かどうかはわかりません。 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()を介して渡されます。

関連する問題