簡體   English   中英

使用boost :: asio處理“對等重置”場景

[英]Handling “reset by peer” scenario with boost::asio

我有一個服務器方法等待新的傳入TCP連接,對於每個連接,我正在創建兩個線程(分離的)來處理各種任務。

    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;
            }
        }
    }

這樣可以很好地啟動通信,但是當客戶端斷開連接並再次連接(或至少嘗試再次連接)時,就會出現問題。

當當前客戶端斷開連接時,我停止通信(通過停止兩個函數的內部無限循環,然后它們將返回)。

    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;
        }
    }

我希望當我重新連接時,通訊應該再次起作用( MyClass::startServer(...)將再次創建和detach兩個工作線程,它們將執行相同的操作。

問題是,當我第二次連接時,我得到:

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. 長度為0且無錯誤的讀取也表示eof。 當您檢查組合操作的結果時,錯誤代碼boost::asio::error::eof通常更有用。

  2. 當錯過此錯誤情況時,顯示的代碼將調用已關閉的套接字上的write 您使用了write形式,該形式沒有引用error_code 出現錯誤時將拋出此表格。 會有錯誤。 讀取失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM