2016-06-23 13 views
0

私は新しい接続TCP接続を待っているサーバーメソッドを持っています。接続ごとに、さまざまなタスクを処理するために2つのスレッドを作成しています。boost :: asioを使って "reset by peer"シナリオを処理する

void MyClass::startServer(boost::asio::io_service& io_service, unsigned short port) { 

     tcp::acceptor TCPAcceptor(io_service, tcp::endpoint(tcp::v4(), port)); 

     bool UARTToWiFiGatewayStarted = false; 

     for (;;) { 

      auto socket(std::shared_ptr<tcp::socket>(new tcp::socket(io_service))); 

      /*! 
      * Accept a new connected WiFi client. 
      */ 
      TCPAcceptor.accept(*socket); 

      socket->set_option(tcp::no_delay(true)); 

      MyClass::enableCommunicationSession(); 

      // start one worker thread. 
      std::thread(WiFiToUARTWorkerSession, socket, this->LINport, this->LINbaud).detach(); 

      // only if this is the first connected client: 
      if(false == UARTToWiFiGatewayStarted) { 

       std::thread(UARTToWifiWorkerSession, socket, this->UARTport, this->UARTbaud).detach(); 

       UARTToWiFiGatewayStarted = true; 
      } 
     } 
    } 

これは、通信を開始するために正常に動作しますが、問題は、クライアントの切断時表示され、再び接続している(あるいは、少なくとも再度接続しようとします)。

現在のクライアントが切断されると、私は通信を停止します(両方の機能から内部の無限ループを停止すると、戻ります)。

私は再接続時に通信が( MyClass::startServer(...)が再び同じことを行うにする2つのワーカースレッドを作成し、 detachます再び動作する必要があることを期待し
void Gateway::WiFiToUARTWorkerSession(std::shared_ptr<tcp::socket> socket, ...) { 

     /*! 
     * various code here... 
     */ 

     try { 
      while(true == MyClass::communicationSessionStatus) { 

       /*! 
       * Buffer used for storing the UART-incoming data. 
       */ 
       unsigned char WiFiDataBuffer[max_incoming_wifi_data_length]; 

       boost::system::error_code error; 

       /*! 
       * Read the WiFi-available data. 
       */ 
       size_t length = socket->read_some(boost::asio::buffer(WiFiDataBuffer), error); 

       /*! 
       * Handle possible read errors. 
       */ 
       if (error == boost::asio::error::eof) { 
        break; // Connection closed cleanly by peer. 
       } 
       else if (error) { 
        // this will cause the infinite loops from the both worker functions to stop, and when they stop the functions will return. 
        MyClass::disableCommunicationSession(); 
        sleep(1); 
        throw boost::system::system_error(error); // Some other error. 
       } 

       uart->write(WiFiDataBuffer, length); 
      } 
     } 
     catch (std::exception &exception) { 
      std::cerr << "[APP::exception] Exception in thread: " << exception.what() << std::endl; 
     } 
    } 

問題は、私が二度目に接続したときにということです私が取得:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >' 
    what(): write: Broken pipe 

私はサーバー(このアプリケーション)が切断されたクライアントへTCP経由で何かを送信しているようです。このエラーについて見つけたものから

私は間違っていますか?

どうすればこの問題を解決できますか?

答えて

1
  1. エラーなしで長さ0を読み取ることは、eofの指標でもあります。 boost::asio::error::eofエラーコードは、通常、合成操作の結果を確認するときに便利です。

  2. このエラー状態が見つからない場合、提示されたコードは、現在シャットダウンされているソケットでwriteを呼び出します。 error_codeを参照していない書き込みの形式を使用しています。このフォームは、エラーがあればスローします。エラーが発生します。読み込みに失敗しました。

+0

私はこれを修正するつもりですが、クライアントが接続を切断すると 'else if(error)'パスを経由するため、これは問題ではないと私は考えています。 –

+0

@MariusMarusaniciは答えをもっと明確にするように更新しました –

+0

それでは、解決策は何でしょうか? –

関連する問題