QTcpSocket 保持活动选项不起作用
QTcpSocket Keep alive option does not work
我有一个简单的程序作为我的客户端,包含一个 tcp 套接字 (QTcpSocket)。我的客户代码如下:
while (tcpSocket.data()->waitForConnected(maxWaitingTimeToConnect) == false)
{
tcpSocket.data()->connectToHost(serverIP, serverPort);
if (maxRetryNumberToConnect != -1 && retryNumber++ > maxRetryNumberToConnect)
{
qDebug() << "Socket is disconnected and maximum try for re-connection reached.";
return false;
}
emit sgl_tryToConnect();
// Socket is disconnected and trying to re-connect
QThread::msleep(100);
}
qDebug() << "Client is connected";
qDebug() << tcpSocket.data()->localPort();
auto sd = tcpSocket.data()->socketDescriptor();
NetworkShared::setSocketOption(&sd);
下面还给出了哪个setSocketOption:
/// Set keepAlive
int enableKeepAlive = 1;
/* Set socket FD's option OPTNAME at protocol level LEVEL
to *OPTVAL (which is OPTLEN bytes long).
Returns 0 on success, -1 for errors. */
qDebug() << setsockopt(*socketDescriptor, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));
int maxIdle = 1; /// Seconds
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
int count = 1; /// Send up to 1 keepalive packets out, then disconnect if no response
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPCNT, &count, sizeof(count));
int interval = 1; /// Send a keepalive packet out every 1 seconds (after the 1 second idle period)
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
当我 运行 我的程序时,一切看起来都很好,并且将为我的套接字启用 keepalive 选项。但是当我在客户端拔下电缆时它不起作用。我将我的 netstat 输出带到下面,表明我的套接字启用了保活计时器。
tcp 0 0 192.168.2.157:37281 192.168.2.163:4444 ESTABLISHED keepalive (0.16/0/0)
我也像客户端一样在服务器端启用了 keepalive 选项。现在我有一些问题; 1- 我什么时候应该启用 keepalive 选项?连接到服务器之后还是连接之前? 2- 我是否应该编写一些代码来捕获程序中的保活错误?
顺便说一下,我的程序是 运行ning 在 linux mint 17.1 中,我还更改了 sysctl.conf 和 proc/sys 中的 keeplalive 选项,但没有用。
在此先感谢您的帮助。
礼萨
最好用Qt的函数setSocketOption:
your_socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
enum QAbstractSocket::SocketOption
This enum represents the options that can be set on a socket. If
desired, they can be set after having received the connected() signal
from the socket or after having received a new socket from a
QTcpServer.
Note: On Windows Runtime, QAbstractSocket::KeepAliveOption must be set before the socket is connected.
并捕获任何连接错误:
connect (your_socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &YourClass::onError);
// ...
void YourClass::onError(QAbstractSocket::SocketError socketError)
{
switch(socketError)
{
case QAbstractSocket::ConnectionRefusedError:
// ...
// ...
}
}
我有一个简单的程序作为我的客户端,包含一个 tcp 套接字 (QTcpSocket)。我的客户代码如下:
while (tcpSocket.data()->waitForConnected(maxWaitingTimeToConnect) == false)
{
tcpSocket.data()->connectToHost(serverIP, serverPort);
if (maxRetryNumberToConnect != -1 && retryNumber++ > maxRetryNumberToConnect)
{
qDebug() << "Socket is disconnected and maximum try for re-connection reached.";
return false;
}
emit sgl_tryToConnect();
// Socket is disconnected and trying to re-connect
QThread::msleep(100);
}
qDebug() << "Client is connected";
qDebug() << tcpSocket.data()->localPort();
auto sd = tcpSocket.data()->socketDescriptor();
NetworkShared::setSocketOption(&sd);
下面还给出了哪个setSocketOption:
/// Set keepAlive
int enableKeepAlive = 1;
/* Set socket FD's option OPTNAME at protocol level LEVEL
to *OPTVAL (which is OPTLEN bytes long).
Returns 0 on success, -1 for errors. */
qDebug() << setsockopt(*socketDescriptor, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));
int maxIdle = 1; /// Seconds
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
int count = 1; /// Send up to 1 keepalive packets out, then disconnect if no response
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPCNT, &count, sizeof(count));
int interval = 1; /// Send a keepalive packet out every 1 seconds (after the 1 second idle period)
qDebug() << setsockopt(*socketDescriptor, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
当我 运行 我的程序时,一切看起来都很好,并且将为我的套接字启用 keepalive 选项。但是当我在客户端拔下电缆时它不起作用。我将我的 netstat 输出带到下面,表明我的套接字启用了保活计时器。
tcp 0 0 192.168.2.157:37281 192.168.2.163:4444 ESTABLISHED keepalive (0.16/0/0)
我也像客户端一样在服务器端启用了 keepalive 选项。现在我有一些问题; 1- 我什么时候应该启用 keepalive 选项?连接到服务器之后还是连接之前? 2- 我是否应该编写一些代码来捕获程序中的保活错误?
顺便说一下,我的程序是 运行ning 在 linux mint 17.1 中,我还更改了 sysctl.conf 和 proc/sys 中的 keeplalive 选项,但没有用。
在此先感谢您的帮助。 礼萨
最好用Qt的函数setSocketOption:
your_socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
enum QAbstractSocket::SocketOption
This enum represents the options that can be set on a socket. If desired, they can be set after having received the connected() signal from the socket or after having received a new socket from a QTcpServer.
Note: On Windows Runtime, QAbstractSocket::KeepAliveOption must be set before the socket is connected.
并捕获任何连接错误:
connect (your_socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &YourClass::onError);
// ...
void YourClass::onError(QAbstractSocket::SocketError socketError)
{
switch(socketError)
{
case QAbstractSocket::ConnectionRefusedError:
// ...
// ...
}
}