在使用boost :: asio写入时立即检测关闭的TCP连接

时间:2017-05-09 13:58:31

标签: c++ multithreading sockets tcp boost-asio

我有一个具有多个客户端/会话的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;
}

2 个答案:

答案 0 :(得分:1)

如果使用异步写入操作,则可以在同一个线程上复用写入,而不会阻塞另一个。你甚至可以为阅读做同样的事。

答案 1 :(得分:0)

为了结束这个问题,我将总结“理查德克里滕”的评论。

问题是连接到我的服务器的客户端没有正常断开连接。如果有正确的断开连接,写入功能将立即中断。为了避免写入操作的长期或无限阻塞,可以配置写入操作在报告错误之前可以花多长时间的超时。可以使用SO_SNDTIMEO套接字选项设置此超时。 http://man7.org/linux/man-pages/man7/socket.7.html