[英]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
向斷開連接的客戶端發送了一些消息。
我做錯了什么?
我怎么解決這個問題?
長度為0且無錯誤的讀取也表示eof。 當您檢查組合操作的結果時,錯誤代碼boost::asio::error::eof
通常更有用。
當錯過此錯誤情況時,顯示的代碼將調用已關閉的套接字上的write
。 您使用了write形式,該形式沒有引用error_code
。 出現錯誤時將拋出此表格。 會有錯誤。 讀取失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.