服务器端的QTcpSocket KeepAliveOption

时间:2017-06-21 15:55:14

标签: qt tcp

我想在服务器端设置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功能正常工作?

由于

3 个答案:

答案 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 时,可能指示重新启动服务器。 最好的问候!