Seite 1 von 1

Verbingsungsverlust wenn Netzwerkkabel gezogen abfangen

Verfasst: 25. Juni 2008 17:15
von Viper2000
Hallo,

nachdem die Beratung im letzten Thread so gut geklappt hat könnt ihr mir auch vielleicht jetzt bei nem neuen Problem helfen!

Ich connecte einen Client zum Server per QTcpServer/QTcpSocket.

Wenn nun das Netzwerkkabel gezogen wird dann "merkt" der Socket das erstmal nicht. Ich hätte eventuell erwartet, dass er dann das "disconnected" Signal ausspuckt.

Kennt jemand nen guten Ansatz um sofort zu erkennen wenn das Netzwerkkabel gezogen wurde und die physikalische Verbindung weg ist? Müsste ja dann irgendwie auf dem Physical Layer irgendwie "bemerkt" werden.

Viele Grüße, viper

Verfasst: 25. Juni 2008 17:54
von PeterLustig
Regelmäßig Ping / Pong senden.

Verfasst: 25. Juni 2008 18:03
von Viper2000
ja das wäre Plan B gewesen :-)

Direkt abfangen kann man sowas nicht?
Zum Beispiel mit nem Timer irgendetwas beim Betriebssystem pollen?

Ansonsten werd ichs über nen PingPing realisieren.

Würdest du das Ping Pong dann auch über nen QTimer realisieren der z.B. einmal pro Sekunde nachsieht ob die Verbindung flöten gegangen ist?

Gruß, viper

Verfasst: 25. Juni 2008 18:38
von PeterLustig
Nur weil ein Netzwerkkabel gezogen wird heißt es ja nicht das die Verbindung weg ist. Und sowieso, der Timer jede Sekunde überprüfen wäre sehr resourcen belastend.. Jede Minute ein kleines Ping/Pong ist die beste Methode.

Verfasst: 25. Juni 2008 19:00
von MiKla
dafür gibt es das TCP keepalive, welches standardmäßig auf 2h eingestellt ist.
Ändern kann man das unter Windows:
http://support.microsoft.com/kb/813827/de
Linux:
http://tldp.org/HOWTO/TCP-Keepalive-HOW ... alive.html

vielleicht hilft es weiter.

Verfasst: 26. Juni 2008 14:16
von Viper2000
Hi PeterLustig,

die Problemstellung im ganzen: Ich sende von einem Client zum Server einen QDataStream in den ein QByteArray eingebettet ist. Das QByteArray enthält Informationen darüber was der Server tun soll(Datenbankabfrage) und der Server schickt dann die Antwort ebenfalls als QDataStream mit QByteArray zurück an den Clienten.

Klappt alles soweit auch wunderbar.

Jetzt ist die Vorgabe aber, dass der Client GANZ SICHER sein muss, dass seine "Anfrage" beim Server ankam. Stichwort Verbindungsverlust. Sollte ich jetzt hingehen und jede Übertragung quittieren lassen? Zum Beispiel:

Client sendet an Server, wartet mit Timer solange bis Quittierung vom Server kommt. Dann empfängt der Client die Antwort vom Server.

Verfasst: 26. Juni 2008 14:47
von patrik08
Da mysql keinen Timeout hat im plugin habe ich einen ScanPort gemacht der ich mit 300 millisekunde starte .... wenn nichts kommt ist eben getrent ....

Code: Alles auswählen


void Gui_Main::CheckHostPort()
{
    //// ShemaConnect  mysql://user:pass@host:3306/database
    ShemaConnect = guiappsetting->lineEdit_3->text();
    if (ShemaConnect.size() < 1) {
    on_actionDatabase_setting_triggered();
    return;
    }
    ScanPort *portcheck = new ScanPort();
    connect(portcheck, SIGNAL(result(int,int,bool)), this,  SLOT(serveracess(int,int,bool)));
    portcheck->SetUrl(QUrl(ShemaConnect),300);
    portcheck->start(QThread::HighPriority);
}

///// serveracess  port / millisekunden / false/true

// .........................

class ScanPort : public QThread
{
    Q_OBJECT
public:
  void SetUrl( QUrl check_url , int maxtime = 1200 , QObject * redirect = 0 )
  {
    url =  check_url;
    receiver = redirect;
    Timeout = maxtime;
    setTerminationEnabled(true);
  }
protected:
void run()
{
    QTime st = QTime::currentTime();
    m_Socket = new QTcpSocket();
    m_Socket->connectToHost(url.host(),url.port(),QIODevice::ReadOnly);
    if (m_Socket->waitForConnected(Timeout))  {
        if (m_Socket->waitForReadyRead(Timeout)) {
            qDebug() << "### connect ok port " << url.port();
            QTextStream *t = new QTextStream( m_Socket );
            t->setCodec(QTextCodec::codecForMib(106));
            int loops = 0;
                   while (!t->atEnd()) {
                      loops++;
                      response = t->readLine();
                      qDebug() << loops << " line  " << response;
                    }
            emit result(url.port(),runtime(st),true);
            quit();
        } else {
        m_Socket->close();
        ////////qDebug() << "### connect nooo on  port " << url.port();
        emit result(url.port(),runtime(st),false);
        quit();
        }
    } else {
        m_Socket->close();
        /////////qDebug() << "### connect nooo on  port " << url.port();
        emit result(url.port(),runtime(st),false);
        quit();
    }
}
int runtime( QTime go )
{
    QTime now = QTime::currentTime();
    return go.msecsTo ( now );
}
signals:
   void result(int,int,bool);  /* port , time , true = ok */
private:
    QString response;
    int Timeout;
    QTcpSocket *m_Socket;
    uint millisecond;
    QUrl url;
    QObject* receiver;
};