PDA

View Full Version : waitForReadyRead and disconnect



matteo.ceruti
23rd November 2012, 16:41
I have a Socket where I wait the data with the function waitForReadyRead (I can't use the singal ReadyRead).
The problem is that I disconnect the network the application crash.
Suggestions?

Thanks
Teo

wysota
23rd November 2012, 17:54
Show your code.

matteo.ceruti
26th November 2012, 10:12
There is one thread to receive data:
void ThreadInputFrameWorkEth::run(void)
{
char vectFrame[1024];
QByteArray byteArrayFrame;
CircularBuffer* lpInput = lpParent->GetInput();
int nCount = 0;
bExit = false;
while (true)
{
//attende che ci siano dei dati. Nel caso di disconnesione o errore
//la bExit viene messa a true anche quando si effettua sconnessione manuale (viene richiamata StopAndWait)
lpParent->waitForReadyRead();
if (bExit)
{
break;
}
...
...
From main thread I create the QTcpSocket and connect to the host

lpSocketChild->connectToHost(data[1].toString(),0xBBBB);
connect(lpSocketChild,SIGNAL(connected()),this,SLO T(Connected()));

When is Connected to keep alive the connection (for windows)
void LocalServer::Connected(void)
{
tcp_keepalive structSettings;
int bOptLen = sizeof (BOOL);
BOOL bOptVal = TRUE;
int nSocketDesctriptor = lpSocketChild->socketDescriptor();
DWORD nBytes = 0;
structSettings.onoff = 1;
structSettings.keepaliveinterval = 500;
structSettings.keepalivetime = 1000;
nRet = ::WSAIoctl(nSocketDesctriptor, SIO_KEEPALIVE_VALS,&structSettings,sizeof(structSettings),NULL,0,&nBytes,NULL,NULL ); // succeeds, r==0
if (nRet == SOCKET_ERROR) //errori da gestire teo da fare forse
{
int nErr = WSAGetLastError();
nRet = -1;
}
nRet = setsockopt(nSocketDesctriptor,SOL_SOCKET,SO_KEEPAL IVE,(char *) &bOptVal,bOptLen);

if (nRet == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
nRet = -2;
}
int nVal = 0;
setsockopt(nSocketDesctriptor, IPPROTO_IP, IP_DONTFRAGMENT,(char *) &nVal, sizeof(nVal));

connect(lpSocketChild,SIGNAL(error(QAbstractSocket ::SocketError)),this,SLOT(Error(QAbstractSocket::S ocketError)));
connect(lpSocketChild,SIGNAL(disconnected()),this, SLOT(DisconnectedSocket()));
}

void LocalServer::Error(QAbstractSocket::SocketError e)
{
((SocketChild*)sender())->SetClosed(true);
}
//----------------------------------------------------------------------------

void LocalServer::Disconnected(void)
{
}
//----------------------------------------------------------------------------

void LocalServer::DisconnectedSocket(void)
{
((SocketChild*)sender())->SetClosed(true);
}
//----------------------------------------------------------------------------

two problems:
1) If I unplug the ethernet cable the application crash.
2) I can't to stop the thread because even if I set from the volatile bool variable bExit to true, the thread is waiting data ("lpParent->waitForReadyRead();) and doesn't control the bExit value if there are not data on the network.


Suggestions?

wysota
26th November 2012, 11:22
1) If I unplug the ethernet cable the application crash.
Where does it crash? Show the backtrace.

amleto
26th November 2012, 13:22
and don't forget code tags ;)

matteo.ceruti
27th November 2012, 18:28
//************* PROVASOCKET.H ***********************
#ifndef PROVASOCKET_H
#define PROVASOCKET_H

#include <QtGui/QMainWindow>
#include <QAbstractSocket>
#include "ui_provasocket.h"

class provasocket : public QMainWindow
{
Q_OBJECT

public:
provasocket(QWidget *parent = 0, Qt::WFlags flags = 0);
~provasocket();

private:
Ui::provasocketClass ui;
private slots:
void Connected(void);
void Error(QAbstractSocket::SocketError e);
void Disconnected(void);
};

#endif // PROVASOCKET_H



//************* PROVASOCKET.CPP ***********************


#include "provasocket.h"
#include <QTcpSocket>
#include <QDebug>
#include <winsock2.h>
#include <mstcpip.h>
#include <ws2tcpip.h>
#include <ws2ipdef.h>
#include <QApplication>
#include "threadread.h"
#pragma comment(lib, "Ws2_32.lib")

QTcpSocket* lpSocket;
ThreadRead* lpThreadRead;
provasocket::provasocket(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
lpSocket = new QTcpSocket();
lpThreadRead = new ThreadRead();
connect(lpSocket,SIGNAL(connected()),this,SLOT(Con nected()));
lpSocket->connectToHost("192.168.15.111",0xbbbb);
}

provasocket::~provasocket()
{
delete lpSocket;
}

void provasocket::Connected(void)
{
tcp_keepalive structSettings;
int bOptLen = sizeof (BOOL);
BOOL bOptVal = TRUE;
int nSocketDesctriptor = lpSocket->socketDescriptor();
DWORD nBytes = 0;
structSettings.onoff = 1;
structSettings.keepaliveinterval = 500;
structSettings.keepalivetime = 1000;
int nRet = ::WSAIoctl(nSocketDesctriptor, SIO_KEEPALIVE_VALS,&structSettings,sizeof(structSettings),NULL,0,&nBytes,NULL,NULL ); // succeeds, r==0
if (nRet == SOCKET_ERROR) //errori da gestire teo da fare forse
{
int nErr = WSAGetLastError();
nRet = -1;
}
nRet = setsockopt(nSocketDesctriptor,SOL_SOCKET,SO_KEEPAL IVE,(char *) &bOptVal,bOptLen);

if (nRet == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
nRet = -2;
}
int nVal = 0;
setsockopt(nSocketDesctriptor, IPPROTO_IP, IP_DONTFRAGMENT,(char *) &nVal, sizeof(nVal));
connect(lpSocket,SIGNAL(error(QAbstractSocket::Soc ketError)),this,SLOT(Error(QAbstractSocket::Socket Error)));
connect(lpSocket,SIGNAL(disconnected()),this,SLOT( Disconnected()));
lpThreadRead->start();
}
//----------------------------------------------------------------------------

void provasocket::Error(QAbstractSocket::SocketError e)
{
qDebug() << "Error";
lpSocket->disconnectFromHost();
}
//----------------------------------------------------------------------------

void provasocket::Disconnected(void)
{
qDebug() << "Disconnected";
}
//----------------------------------------------------------------------------




//************* PROVASOCKET.H ***********************
#ifndef THREADREAD_H
#define THREADREAD_H

#include <QThread>

class ThreadRead : public QThread
{
Q_OBJECT

public:
ThreadRead();
~ThreadRead();
volatile bool bExit;

protected:
void run(void);
};

#endif // THREADREAD_H


//************* PROVASOCKET.CPP ***********************

#include "threadread.h"
#include <QTcpSocket>
#include <QApplication>
extern QTcpSocket* lpSocket;

ThreadRead::ThreadRead()
: QThread()
{

}

ThreadRead::~ThreadRead()
{

}

void ThreadRead::run(void)
{
bExit = false;
while (!bExit)
{
while (lpSocket->waitForReadyRead(5000))
{
if (bExit)
{
return;
}
QApplication::processEvents();
}
}
}


If I unplug the ethrnet cable the next


while (lpSocket->waitForReadyRead(5000))

crash.

Thanks
Teo

wysota
27th November 2012, 20:28
Show the backtrace please.