2017-12-03 29 views
1

複数のクライアントからのメッセージを受け取り、N個のデータを受け取り、このデータのバッチを処理し、すべてのクライアントに返信を「完了」するまで、メッセージを受け入れるサーバーを作成しようとしています。ソケット:複数のクライアントにメッセージを送信

このコードは、クライアントからデータを受け取った直後にクライアントにメッセージ「完了」を送信すると正常に動作します。どのようにして、すべてのクライアントを "保存"し、後でバッチ処理後にメッセージを送信することができますか?

while (true) { 
    listen(sock, 1000); 
    newsock = accept(sock, (struct sockaddr *) &cli_addr, &clilen); 
    n = read(newsock, buffer, read_len); 
    if (n < 0) { 
     cout << "ERROR reading from the socket" << endl; 
     continue; 
    } 
    memcpy(data + (msg_count * tuple_size), buffer, tuple_size); 
    n = write(newsock, "done\n", 5); //sending the message to the current client 
    msg_count++; 
    if (msg_count >= batch_size) { 
     msg_count = 0; 
     doSomethingWithTheData(data); 
     //I want to send the message to all the clients here 
    } 
    bzero(buffer, read_len); 
} 
+0

Cookieを設定しましたか? – Arash

+0

@ArashMohammadiいいえ、私はそれらを試していない、私は今それについて読むつもりです。サーバーとすべてのクライアントが同じPCにある場合、クッキーは機能しますか? – vgeclair

+0

クライアントが複数のメッセージを送ることができる場合は、 'select'か' epoll'を調べたいかもしれません。 – user4581301

答えて

1

このようなものを試してください。

while (true) { 
    std::list<int> socks; 
    listen(sock, 1000); 
    newsock = accept(sock, (struct sockaddr *) &cli_addr, &clilen); 
    n = read(newsock, buffer, read_len); 
    if (n < 0) { 
     cout << "ERROR reading from the socket" << endl; 
     continue; 
    } 
    memcpy(data + (msg_count * tuple_size), buffer, tuple_size); 
    socks.push_back(newsock); 
    msg_count++; 
    if (msg_count >= batch_size) { 
     msg_count = 0; 
     doSomethingWithTheData(data); 

     //I want to send the message to all the clients here 
     msg_count -= socks.size(); 
     while (!socks.empty()) { 
      newsock = socks.front(); 
      n = write(newsock, "done\n", 5); //sending the message to the current client 
      close(newsock); 
      socks.pop_front(); 
     } 
    } 
    bzero(buffer, read_len); 
} 

はFYI bzero()関数は(POSIX.1-2001でLEGACYとしてマーク)は推奨されません:新しいプログラムではmemset(3)を使用します。 POSIX.1-2008はbzero()の指定を削除します

+0

正しい。とにかく、vgeclairのような何かをやらなければなりません。なぜなら、現在のところ靴下を解放せずにしか靴下を割り当てていないからです。 – user2328447

+0

私はそれを試しましたが、この行に "壊れたパイプ"エラーが発生します: 'n =書き込み(sock、done \ n"、5); ' ' sock'を'newsock'ではなく、リスト?それは常に同じ価値を持っているようです。 – vgeclair

+0

@vgeclairが正しいようです。 'sock'はあなたが聞いているソケットであり、クライアントに接続しているソケットではありません。 – user4581301

-1

zeroMqを試しましたか? たとえばhttp://zguide.zeromq.org/cpp:rrworker

+0

いいえ、私はそれを試していない。いくつかのクライアントを覚えておくことはどのように役立ちますか? – vgeclair

+0

私の考えは、クライアントがフロントエンドソケットに接続してバッチワーカーにディスパッチする場合に、 nクライアントがリクエスト - 応答パターを延長することでした。 作業員がnクライアントに対してジョブのフロントエンドソケット応答を完了した後 – fbalicchia

関連する問題