我正在使用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