2016-12-20 16 views
0

クライアントとしてTCPソケット(QTcpSocket)で構成された簡単なプログラムがあります。QTcpSocketキープアライブオプションが機能しません

も以下に与えられるsetSocketOption
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); 

:私のクライアントのためのコードは以下に示す。私は私のプログラムを実行すると

/// 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タイマーが私のソケットのために有効になっているincdicate以下のnetstat出力を持ってきました。

tcp  0  0 192.168.2.157:37281  192.168.2.163:4444  ESTABLISHED keepalive (0.16/0/0) 

私はまた、クライアント側と同様にサーバー側にキープアライブオプションを有効にしました。今私はいくつか質問があります。 1-キープアライブオプションを有効にする必要があるのはいつですか?サーバーに接続した後、または接続する前に?私のプログラムでキープアライブエラーを捕まえるためのコードを書くべきですか?

ところで、私のプログラムはlinux mint 17.1で動作しており、sysctl.confとproc/sysのkeeplaliveオプションもvailなしに変更しました。

ご協力いただきありがとうございます。 はレザ

+1

'netstat'出力は、それが仕事をしていることを示しています。あなたが何を求めているのか不明です。 – EJP

+0

[以前に接続されたSSL/TCPソケットのインターネット切断を検出する方法](http://stackoverflow.com/questions/37116838/how-to-detect-internet-disconnection-on-ssl-tcp-ソケットが接続されていた) – iammilind

+0

スイッチが切断されたときに[QAbstractSocket :: disconnected()信号が出ない](http://www.qtcentre.org/archive/index.php/t- 29469.html)。代わりに、さまざまな 'waitfor ...()'メソッド(つまり 'waitForReadyRead(milliseconds)')を使うことも考えられます。タイムアウトを望ましい量に設定し、その間に接続が有効かどうかを確認することもできます。ところで、私はQtが初めてです。実際の問題に対する解決策を見つけましたか? @EJP、私はOPがインターネットプラグが抜かれても(私が正しく理解していても)ソケットが切断されないという問題があると思います。 – iammilind

答えて

0

Qtの機能setSocketOption使用する方がよいでしょう:

your_socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); 

列挙QAbstractSocket :: SocketOption

この列挙は、ソケット上で設定できるオプションを表します。 が必要な場合は、ソケットからconnected()シグナル を受信した後、または QTcpServerから新しいソケットを受信した後で設定できます。

注: Windowsランタイムでは、ソケットが接続される前にQAbstractSocket :: KeepAliveOptionを設定する必要があります。

とキャッチのための任意の接続エラー:あなたが投稿した

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: 
     // ... 
     // ... 
    } 
} 
+0

それはなぜでしょうか? – EJP

+1

@EJP、Qtには独自の関数があるので、その場合はQtとシステム関数を混在させるのが奇妙です。また、Qtはクロスプラットフォームのフレームワークです –

+0

無関係です。 'setsockopt()'が-1を返さなければ、それははっきりと働いているので、これがOPの問題をどのように解決するのでしょうか? – EJP

関連する問題