PDA

View Full Version : TCP Socket not connecting on Release



^NyAw^
20th May 2008, 10:53
Hi,

I'm using a QTcpSocket that tryies to connect to a client. The code is working when the application is compiled on Debug mode but when I try using Release mode, I recive this error "QAbstractSocket::RemoteHostClosedError".

Any idea what is happenging?

Thanks,

^NyAw^
20th May 2008, 13:05
Hi,

Tryied to create another client application and, sending this(char[])


char data[12];
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
data[4] = 0;
data[5] = 6;
data[6] = 1;
data[7] = 3;
data[8] = 0;
data[9] = 0;
data[10] = 0;
data[11] = 1;


I reccive:



char data[12];
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
data[4] = 6; // !!
data[5] = 6;
data[6] = 1;
data[7] = 3;
data[8] = 0;
data[9] = 0;
data[10] = 1; //!!
data[11] = 1;


This only happens when the sender app is on Release mode, but when using on Debug mode the recived data is correctly.

Thanks,

wysota
20th May 2008, 15:30
What code did you use for sending and receiving the data?

^NyAw^
20th May 2008, 15:40
Hi,

I'm using the "QIODevice::write" method.

The socket is running on a working thread. Used the "threadedfortuneserver" as example to write this code:



void myThread::run()
{
m_pqSocket = new QTcpSocket();
bool bC2 = connect(m_pqSocket,SIGNAL(error(QAbstractSocket::S ocketError)),this,SLOT(ErrorConexio(QAbstractSocke t::SocketError)));
m_pqSocket->connectToHost(m_qIPSlave,502,QIODevice::ReadWrite) ;
if (m_pqSocket->waitForConnected(5000))
{
exec();

//When exiting the eventLoop:
m_pqSocket->disconnectFromHost();
if (m_pqSocket->waitForDisconnected(5000))
delete (m_pqSocket);
}
else
{
//If not connected
delete (m_pqSocket);
}
}


When using Debug version, on console I'm getting this messages:


QSocketNotifier: socket notifiers cannot be enabled from another thread
QSocketNotifier: socket notifiers cannot be disabled from another thread


Thanks,

wysota
20th May 2008, 15:42
What about the rest of the code? Could you paste the exact code used for reading and writing?

^NyAw^
20th May 2008, 16:12
Hi,

Sorry, I'm developing Modbus protocol and I have some layers. The layer that I show you is the CModbusTCPMaster, and the socket is delivered to the CModbusTCPTransport:

I had simplified it because it's a bit large code.



void CModbusTCPTransport::setSocket(QTcpSocket* pqSocket)
{
bool bC1 = connect(m_pqTCPSocket,SIGNAL(readyRead()),this,SLO T(readResponse()));
bool bC2 = connect(m_pqTCPSocket,SIGNAL(disconnected()),this, SLOT(disconect()));
}


void CModbusTCPTransport::sendRequest(CModbusRequest* request)
{
int iLength = 8;
char* pcRequest = new char[260];
pcRequest[0] = request->getTransaction() >> 8;
pcRequest[1] = request->getTransaction();
pcRequest[2] = request->getProtocol() >> 8;
pcRequest[3] = request->getProtocol();
pcRequest[4] = request->getLength() >> 8;
pcRequest[5] = request->getLength();
pcRequest[6] = request->getUnitID();

pcRequest[7] = request->getFunctionCode();

m_pqTCPSocket->write(pcRequest,iLength);
//Force the Request to be sent
m_pqTCPSocket->flush();
delete[] pcRequest;
}

void CModbusTCPTransport::readResponse()
{
//Read the Modbus Header (8 bytes)
qint64 bytesRead = m_pqTCPSocket->read(m_cbuffer,8);
}
Thanks,

^NyAw^
20th May 2008, 17:08
Hi,

Creating a QObject inside "run()" method of the Thread, shows this error:


void myThread::run()
{
...
QObject ob(this);
}


QObject: Cannot create children for a parent that is in a different thread.
(Parent is CModbusTCPMaster(02BCAAB0), parent's thread is QThread(019480E0), current thread is CModbusTCPMaster(02BCAAB0)

I tryied this because when creating the socket, no parent is passed to it. But trying to use "this" as the socket parents gets me the same error.

Thanks,

^NyAw^
20th May 2008, 18:01
Hi,

I have an idea how to solve this:
-Create a QTcpSocket dervied class that has a SLOT "sendMessage(char*)"
-My Thread emits a SIGNAL "readySend(char*)" that is connected to the SLOT of the QTcpSocket derived class on a QueuedConnection.

The problem is that when calling "pqTcpSocket->write", this is done by myThread.

Thanks,

^NyAw^
20th May 2008, 18:42
Hi,

The QSocketNotifier messages have disapeared using this behaviour.

The other problem that the server application is not accepting the connection is still getting me errors, but using a simple Qt server aplication it connects well. So, I really don't understand why the other server application is reaching the connection with "QAbstractSocket::RemoteHostClosedError" error code(note that is a third party app that I don't have the source code).

And finally, the problem that the server recives a different message ... is still getting me a different message.

Thanks,

wysota
20th May 2008, 19:09
But trying to use "this" as the socket parents gets me the same error
Because the child and parent objects are created in different threads and this is forbidden. Don't try to pass a parent.


And finally, the problem that the server recives a different message ... is still getting me a different message.

Are the sender and receiver machines of the same architecture (32/64b big/little endianness)?

Could you check using a network sniffer whether the content "turns incorrect" on the client or on the server? In other words - what is being transmitted over the network? The data that is being sent or the one that is being received?

^NyAw^
20th May 2008, 19:34
Hi,

I'm using the same machine to use client and server apps. A Windows XP OS on a 32 bit machine and Qt 4.3.0.

Wireshark sniffer is not able to capture packages from/to the same machine, so I open a QFile and write the message(increasing by 48 to convert int to char ona ASCII) into it.

The data that the client is sending is wrong when using Release but it's okay when running on Debug.

Thanks,

Bitto
20th May 2008, 19:54
Ã’scar, I'm sure everybody would like to help, but if you want an accurate answer, you will have to isolate your problem, and post a standalone compilable example that shows the bug.

Usually differences in behavior between debug and release in networking code are caused by either

1) Timing problems (i.e., race conditions)
* the order of packet arrival affects you program's logics

2) Network packet fragmentation (i.e., partial packet arrival)
* the size of packets received affects your program's behavior

3) Compiler bugs
* _usually_ triggered by complex code, try simplifying

Generally though I'd try to simplify and simplify your code until you have something that's still broken, but can be posted to this forum for review :-).

^NyAw^
20th May 2008, 20:07
Hi,



1) Timing problems (i.e., race conditions)
* the order of packet arrival affects you program's logics

Really do you thing that I do different things on Debug and on Release?



2) Network packet fragmentation (i.e., partial packet arrival)
* the size of packets received affects your program's behavior

The packet size is as maximum 20 bytes long. Dou you really thing that it is packed on different little packages? But, when Debugging the packages that I recive are ok.



3) Compiler bugs
* _usually_ triggered by complex code, try simplifying

Simply I can't.

Will try to reproduce the problem.

^NyAw^
20th May 2008, 20:33
Hi,

Could this code:


quint16 qAdd = request->getRegisterAddress();
pcRequest[8] = (char)(qAdd >> 8);
pcRequest[9] = (char)qAdd;



Get different values on Debug and on Release?
What I want is
to get the MSB 8 bits of "qAdd" to pcRequest[8] and the LSB 8 bits to pcRequest[9].
This is well done on Debug and not on Release?

Bitto
20th May 2008, 21:47
You can add qDebugs to find out :-).

^NyAw^
21st May 2008, 00:08
Hi,

I don't really know if you are jocking. Have your read that the problem is in Release mode? So "qDebug" will get me ... ah, nothing.

The problem was that I used this code:


pcRequest[0] = request->getTransaction() >> 8;
pcRequest[1] = request->getTransaction();

That on Debug gets me this result(p.ex. "request->getTransaction()" returns 1):
pcRequest[0] == 0;
pcRequest[0] == 1;

And returns me this on Release:
pcRequest[0] == 1;
pcRequest[0] == 1;

The new code that I used is this:


quint16 qTrans = request->getTransaction();
pcRequest[0] = (char)(qTrans >> 8);
pcRequest[1] = (char)qTrans;


So, the problem that reciving different data is solved. Problem of the compiler and a mine mishap.


The other problem that the server reaches the connection is not solved yet. Any help will be usefull.

Thanks,

wysota
21st May 2008, 09:32
So "qDebug" will get me ... ah, nothing.
No, it won't. And you can always use std::cerr if you want :)


The other problem that the server reaches the connection is not solved yet. Any help will be usefull.

Try isolating the problem using a minimal compilable example that we could check ourselves. At least post the code used to setup the server and accept connections.

^NyAw^
21st May 2008, 10:26
Hi,



Try isolating the problem using a minimal compilable example that we could check ourselves. At least post the code used to setup the server and accept connections.


As I said, the server is a Third party app that I don't have the source. I've created a minimal server app using Qt and it accept the connection that the 3rd party app don't accept(only on release), so there could be a problem on the 3rd party app. I use this code into "run()" method:


m_pqSocket->connectToHost(m_qIPSlave,502,QIODevice::ReadWrite) ;
if (m_pqSocket->waitForConnected(5000))
{
...
}



And I can see that it don't wait the 5 seconds to connect. In the moment that the socket tryies "waitForConnected" it returns inmediatly(only on release). So, maybe is there any bug on the 3rd party app network libs, but don't worry about it, I use this app to ensure that my Modbus protocol works fine and this is the only problem that I'm having.

Thanks for your time,