PDA

View Full Version : Transfer image problem



probine
3rd May 2006, 00:59
I have two computers. They are able to send text messages to each other, but as soon as I want to pass an image the program crashes.

To read the sent data I am using "readAll();"

How do I solve this ?

jacek
3rd May 2006, 01:09
How do I solve this ?
Use a debugger and try to obtain the stack trace --- it will show you where your program crashed.

If you have gdb, try this:
$ gdb ./application
(gdb) run
<program starts and crashes>
(gdb) bt
<backtrace>
(gdb) quit(just make sure that you have compiled your program in debug mode).

If you use windows make sure you have "CONFIG += console" in the .pro file, so that you can see all messages from Qt.

probine
3rd May 2006, 01:20
You are suggesting that the problem is somewhere else then.

This is what happens:

1. When the 2 clients (program) are running in the same machine as the server, then the image is passed successfully.

2. When I run the server and 1 client in Linux, and the other client in Windows, then the program crashes.

When I pass regular text messages, then everything is fine, because the messages are small. I have a "cout<<" in the server that prints IMAGE everytime the payload is greater than 500.

readAll(); is executed everytime a payload arrives, so in the screen I see many IMAGE messages, because the image is large.

I thought that readAll(); will take care of it, but I may be wrong.



// Creates the needed connections
void ClientThread :: iniConnections()
{
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
}


// Reads all incoming data and passes it to the message class
void ClientThread :: readData()
{
messageIn->clear();
*messageIn = tcpSocket->readAll();
if(messageIn->length() >= 500)
{
cout << "SCREENSHOT\n";
remoteClientThread->directScreenshot(*messageIn);
}
else
message->parseMessage(*messageIn);
}


I know that the problem is in this readAll(); because the image is passed in pieces and the program cannot display those pieces.

How can I collect all the image coming from the remote computer in my QByteArray before passing the image to the label ?

jacek
3rd May 2006, 15:17
How can I collect all the image coming from the remote computer in my QByteArray before passing the image to the label ?

You need something like this:
void ClientThread :: readData()
{
buffer.append( tcpSocket->readAll() );
int messageSize = 0;
do {
messageSize = parseMessage( buffer );
buffer.remove( 0, messageSize );
}
while( messageSize > 0 );
}
There are three possibilities: the buffer contains only a part of a message (in this case parseMessage() should only return 0),
the buffer contains a message followed by a part of another message (in this case parseMessage() should parse that message and return its size),
the buffer contains an invalid message (it might happen due some communication errors or bugs on the other side).

probine
4th May 2006, 00:38
I understand what you are saying... thanks fot answering.

The problem I have is that the QByteArray is passed to the respective function to be treated before I was able to store all the data in it.

Example:

A client sends an image. The size of the image is variable, but in this case lets say 5000 bytes.

The server starts receiving the image, but it only received 1250, so the server should wait and append the rest of the image to the QByteArray.

Is there a function in QTcpSocket that tells me the total size of the package ??? in this case will be 5000.

jacek
4th May 2006, 02:38
Is there a function in QTcpSocket that tells me the total size of the package ??? in this case will be 5000.
No, with TCP you receive just a stream of bytes --- it's your job to determine where the message ends. If you were using QDataStream, Qt could help you a bit with this.

probine
4th May 2006, 10:40
How could I determine where the package ends ?

jpn
4th May 2006, 11:24
Pass the length of the image as the first field of your message, and/or define an end mark which you always append to the end of the message.