我想在服务器端设置QTcpSocket :: KeepAliveOption,以便在网络连接丢失一段时间后自动断开连接。
然而,文档说:
在Windows运行时,必须在连接套接字之前设置QAbstractSocket :: KeepAliveOption。
在客户端上,您只需创建套接字,设置选项,然后连接它。
在服务器端,您不创建套接字,它们被创建并返回购买QTcpServer :: nextPendingConnection()。这些已经连接。
所以我基本上被卡住了,并且是唯一可行的选择来实现"心跳"自己?
修改
我已根据talamaki的建议创建了一个QTcpServer子类,用于设置传入连接套接字上的标志:
class CustomTcpServer : public QTcpServer
{
Q_OBJECT
public:
CustomTcpServer(QObject * parent = 0) : QTcpServer(parent) { }
void incomingConnection(qintptr socketDescriptor)
{
QTcpSocket *socket = new QTcpSocket(this);
socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
socket->setSocketDescriptor(socketDescriptor);
addPendingConnection(socket);
}
};
然后,我已经设置了
\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters\KeepAliveTime
DWORD值为30000(30秒)
重新启动系统以确保它被系统使用
但是,在拔掉远程客户端的以太网电缆后,几分钟后我仍然没有断开信号。
如何使KeepAlive功能正常工作?
由于
答案 0 :(得分:0)
您应该能够覆盖QTcpServer::incomingConnection并自己创建QTcpSocket,而不是让框架执行此操作。
答案 1 :(得分:0)
在Windows上,AFAIK有三个参数来控制TCP连接的超时。您已设置KeepAliveTime,这是空闲连接将开始发送保持活动段的时间(连接必须空闲,没有已发送段,没有收到Ack)。然后有一些需要无人接听的保持活动以确定它已经死亡,这是TcpMaxDataRetransmissions。最后,保持活动段之间的时间是KeepAliveInterval。如果正在发送空TCP段(这是Keep-Alives),请与Wireshark一起检查。某些版本的Windows也可能会出现异常,并忽略某些设置。
答案 2 :(得分:0)
通常服务器会在一段时间没有流量后重新启动侦听。在 close en re-open 之后,新的连接将到达。
客户端和服务器也可以指定一个测试协议,如以 X 秒、分钟等为间隔的 PING - PONG 消息
在服务器端,当 X 秒后丢失 ping 时,可能指示重新启动服务器。 最好的问候!