TCP KeepAlive判断离线的记录
问题描述:
出现过建立TCP连接的目标设备离线以后,这边检测不到离线,导致出现逻辑错误。
原因分析:
原因就是没有设置TCP KeepAlive的保活机制,因为默认情况下这个是关闭的。
解决方案:
在创建套接字以后,通过设置SO_KEEPALIVE、TCP_KEEPIDLE、TCP_KEEPINTVL、TCP_KEEPCNT来判断是否离线
int on = 1;
if (setsockopt(socktmp, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof(on)) < 0) {BLOG_ERROR(fmt::format("SO_KEEPALIVE failed {}:{}", m_addr, m_addr_port));
}int keepIdle = 2; // 2秒无活动后开始探测
int keepIntvl = 3; // 探测间隔3秒
int keepCnt = 3; // 最多探测3次
if (setsockopt(socktmp, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&keepIdle, sizeof(keepIdle)) < 0) {BLOG_ERROR(fmt::format("TCP_KEEPIDLE failed {}:{}", m_addr, m_addr_port));
}
if (setsockopt(socktmp, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&keepIntvl, sizeof(keepIntvl)) < 0) {BLOG_ERROR(fmt::format("TCP_KEEPINTVL {}:{}", m_addr, m_addr_port));
}
if (setsockopt(socktmp, IPPROTO_TCP, TCP_KEEPCNT, (char*)&keepCnt, sizeof(keepCnt)) < 0) {BLOG_ERROR(fmt::format("TCP_KEEPCNT {}:{}", m_addr, m_addr_port));
}