boost :: asio :: ip :: tcp :: socket是否已连接?

coe*_*udo 18 c++ sockets boost-asio

我想在执行读/写操作之前验证连接状态.

有没有办法制作isConnect()方法?

我看到了这一点,但似乎"丑陋".

我也测试了is_open()函数,但它没有预期的行为.

jos*_*rry 31

面对严酷的网络,TCP意味着强大; 即使TCP提供了看似持久的端到端连接,但这只是一个谎言,每个数据包实际上只是一个独特的,不可靠的数据报.

连接实际上只是虚拟管道,在连接的每一端都跟踪了一个小状态(源和目标端口和地址,以及本地套接字).网络堆栈使用此状态来了解将每个传入数据包分配给哪个进程以及将每个传出数据包的标头放入哪个状态.

虚拟TCP管道

由于网络的基础 - 固有的无连接和不可靠 - 性质,当远程端发送FIN数据包以关闭连接时,或者如果它没有收到对发送的数据包的ACK响应,则堆栈将仅报告断开的连接(在超时和几次重试之后).

由于asio的异步性质,通知正常断开连接的最简单方法是在连接关闭时立即async_read返回error::eof.但仅此一点仍然存在其他问题,如半开放连接和网络问题未被发现的可能性.

解决意外连接中断的最有效方法是使用某种keep-alive或ping.偶尔通过连接传输数据的尝试将允许方便地检测无意切断的连接.

TCP协议实际上有一个内置的保持活动机制,可以使用asio进行配置asio::tcp::socket::keep_alive.TCP keep-alive的优点在于它对用户模式应用程序是透明的,只有对keep-alive感兴趣的对等体才需要配置它.缺点是您需要操作系统级访问/知识来配置超时参数,遗憾的是,它们不会通过简单的套接字选项公开,并且通常具有非常大的默认超时值(Linux上为7200秒).

保持活动最常用的方法可能是在应用程序层实现它,在应用程序层,应用程序有一个特殊的noop或ping消息,除了响应时做什么都没做.此方法为您提供实现保持活动策略的最大灵活性.