我正在使用boost::asio
同步 TCP 套接字连接到在同一台计算机上运行的 node.js TCP 服务器应用程序。我在 Windows 上使用 Embarcadero RAD studio XE4 构建使用 Embarcadero 集成升压版本 1.50 的 64 位应用程序。
除非 node.js TCP 服务器关闭,否则一切正常。发生这种情况时,我的 C++ 客户端应用程序在我从套接字读取时未检测到断开连接。但是,当我写入套接字时,它确实检测到断开连接。
我当前的代码是在尝试理解 boost 文档和 SO 上的各种答案后编写的。代码的阅读部分如下(我省略了对错误代码紧凑性的检查)
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()
,当那里没有数据时,我不会在套接字上执行 a ,但在这种情况下我会这样做,因为所有文档都让我相信只有在对套接字执行读取或写入时才会检测到套接字断开连接。问题是,当 node.js 应用程序关闭时,上面的代码根本不会检测到断开连接。如果我正在写作,我会检测到它(代码的写入部分使用与读取相同的 boost::asio::error` 错误进行检测)但在读取时不会。
显然,我无法读取大于可用的字节数,否则我的线程将阻塞,并且稍后我将无法在我的线程循环中执行写入。
我是否缺少另一个特定的提升错误代码来检测错误情况?或者是零长度读取的问题。如果是这种情况,我还有其他选择吗?
目前,我正在让 node.js 服务器在它关闭时向套接字写出一条特定的消息,我正在检测它,然后自己关闭客户端。但是,这有点小技巧,如果可能的话,我更喜欢一种干净的方法来检测断开连接。