我正在使用boost::asio
與運行在同一臺計算機上的node.js TCP服務器應用程序建立同步TCP套接字連接。我正在Windows上使用Embarcadero RAD studio XE4構建使用Embarcadero集成boost版本1.50的64位應用程序。無法檢測正在關閉的C++同步boost :: asio :: ip :: tcp :: socket連接
事情工作正常,除非node.js TCP服務器關閉。發生這種情況時,我從套接字讀取時,C++客戶端應用程序不檢測到斷開連接。但是,當我寫入套接字時它會檢測到斷開連接。
我現在的代碼是在嘗試理解SO上的boost文檔和各種答案後編寫的。代碼的讀取部是如下(I已省略了緊湊的錯誤代碼的檢查)
boost::system::error_code ec;
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket s(io_service);
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"),m_port);
ec = s.connect(ep,ec);
std::size_t bytes_available = s.available(ec);
std::vector<unsigned char> data(bytes_available,0);
size_t read_len = boost::asio::read(s, boost::asio::buffer(data),boost::asio::transfer_at_least(bytes_available),ec);
if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
{
// disconnection
break;
}
這不是一個很大的系統,因爲它是在其自己的線程中運行的環路和輪詢數據內不斷直到程序關閉。在沒有數據的情況下,通常我不會在套接字上執行read()
,但是在這種情況下我會這樣做,因爲所有文檔都使我相信只有在執行讀取或寫入套接字時纔會檢測到套接字斷開連接。問題在於,上面的代碼在node.js應用程序關閉時根本不會檢測到斷開連接。如果我正在寫,我發現它(代碼的寫入部分使用相同的boost :: asio :: error`錯誤作爲檢測讀取),但讀取時不會。
很明顯,我無法執行讀取的字節數量大於可用的或我的線程將阻止,我將無法執行後來寫入我的線程循環。
我是否缺少另一個特定的增強錯誤代碼來檢測錯誤情況?或者這是零長度讀取特別的問題。如果是這種情況,我還有其他選擇嗎?
目前我得到的node.js服務器寫出一個特定的消息,當它關閉時,我檢測到,然後關閉客戶端自己的套接字。但是,這有點破解,如果可能的話,我寧願採用乾淨的方式來檢測斷開連接。
謝謝您的回答。不幸的是,它不能解決我的問題,因爲即使沒有讀取任何東西,我也需要重新寫回套接字。我的應用程序有點像WebSocket,即使沒有收到任何讀取數據,我也需要將數據推回到另一端。因此,我無法承擔任何**封鎖電話。也許我現在的方案只需要更改爲異步。 – mathematician1975
@ mathematician1975異步可能是理想的解決方案,但這仍然可以通過同步調用完成。我已經更新了答案,以演示如何以非阻塞方式觀察與同步'read()'操作的斷開連接。 –
非常感謝您的更新。我沒有遇到將套接字設置爲非阻塞的選項,所以這非常有幫助。 – mathematician1975