我有一个具有多个客户端/会话的TCP服务器。每个会话都有自己的线程,用于从客户端接收数据,但只有一个线程(" writeThread")响应所有客户端。
现在问题是,如果客户端在" writeThread"期间关闭了连接。写入此套接字需要几秒钟,直到写入操作注意到远程关闭连接。有时候它根本就没有通知,就在我手动为已安装的sighandler发送signal
时,应用程序将检测它并中断写入操作。
时间是在Logger::trace("start write");
和Logger::trace("remote term, closed socket ");
尽管这可能不是最好的设计,是否有可能立即检测到已关闭的连接,或者我是否真的需要重新设计?
bool myWrite(UINT8 *pu8_buffer, UINT32 u32_size)
{
bool b_success = false;
try
{
Logger::trace("start write");
b_success = (u32_size == boost::asio::write(_x_socket, boost::asio::buffer(pu8_buffer, u32_size)))
}
catch (boost::system::system_error &er)
{
if (er.code() == boost::asio::error::eof ||
er.code() == boost::asio::error::connection_reset)
{
boost::system::error_code x_er;
_x_socket.close(x_er);
if (!x_er)
{
Logger::trace("remote term, closed socket ");
}
else
{
Logger::err("remote term, closed socket failed");
}
}
}
catch(std::exception &ex)
{
Logger::err("write exception\n\t",ex.what());
}
catch(...)
{
Logger::err("write unknown exception",(uint32_t)this);
}
return b_success;
}
答案 0 :(得分:1)
如果使用异步写入操作,则可以在同一个线程上复用写入,而不会阻塞另一个。你甚至可以为阅读做同样的事。
答案 1 :(得分:0)
为了结束这个问题,我将总结“理查德克里滕”的评论。
问题是连接到我的服务器的客户端没有正常断开连接。如果有正确的断开连接,写入功能将立即中断。为了避免写入操作的长期或无限阻塞,可以配置写入操作在报告错误之前可以花多长时间的超时。可以使用SO_SNDTIMEO
套接字选项设置此超时。 http://man7.org/linux/man-pages/man7/socket.7.html