PDA

View Full Version : problem with QByteArray data !



Con Nít
23rd January 2011, 16:04
i am writing a chat application using TCP.
i found a simple exemple of text chat here : http://www.qtcentre.org/wiki/index.php?title=Simple_chat.
i edited its code so that it can send QByteArray data instead of Qstring like it did in the beginning,but after editing, Server didn't send back message to clients.
help me fix my code.

a part of simplechatclient.cpp :

void SimpleChatClient::sendMessage()
{
if(socket == NULL) return;
if(socket->state() != QAbstractSocket::ConnectedState ) return;
QString msg = "TEXT";
QString data = "<" + nick->text().toLatin1() + "> " + message->text().toLatin1() + "\n";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_2);
out << (quint32) 0;
out << msg;
out << data;
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));

socket->write(block);
socket->flush();
message->clear();
QMessageBox::information( new QWidget, "Application name",
"Client send ok." );
}

void SimpleChatClient::receiveMessage()
{
if (socket == NULL) return;
if (socket->state() != QAbstractSocket::ConnectedState) return;

QDataStream in(socket);
in.setVersion(QDataStream::Qt_4_2);
//in.setVersion( in.version() ); // set to the current Qt version instead

if(blockSize == 0) {
if (socket->bytesAvailable() < (int)sizeof(quint32)) return;
in >> blockSize;
}

if(socket->bytesAvailable() < blockSize) return;
QString msgString;
QString msgData;
in >> msgString;
in >> msgData;

chat->append(msgData);

blockSize = 0;

if(socket->bytesAvailable() > 0) receiveMessage();
}

a part of simplechatsever.cpp :

void SimpleChatServer::receiveMessage()
{
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());

if (socket == NULL) return;
if ( socket->state() != QAbstractSocket::ConnectedState ) return;

QDataStream in(socket);
in.setVersion(QDataStream::Qt_4_2);

if (blockSize == 0) {
if (socket->bytesAvailable() < (int)sizeof(quint32)) return;
in >> blockSize;
}
if (socket->bytesAvailable() < blockSize) return;
QString msgString;
QString msgData;
in >> msgString;
in >> msgData;

emit onMessage( msgString, msgData );
blockSize = 0;
if (socket->bytesAvailable() > 0) receiveMessage();

}
void SimpleChatServer::onMessage(const QString &msg, const QString &data)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_2);
out << (quint32) 0;
out << msg;
out << data;
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));
foreach (QTcpSocket* connection, connections)
{
connection->write(block);
connection->flush();
}
}

high_flyer
23rd January 2011, 17:01
i edited its code so that it can send QByteArray data instead of Qstring like it did in the beginning,but after editing, Server didn't send back message to clients.
I hope you don't expect us to go to the other thread, and compare the code there with your code.
Please post the changes you made so that we can see them in relation to the original.

Con Nít
23rd January 2011, 17:23
i' sorry .

this is the original code :

a part of simplechatclient.cpp :

void SimpleChatClient::sendMessage()
{
// "<nick> message\n"
socket->write("<" + nick->text().toLatin1() + "> " + message->text().toLatin1() + "\n");
message->clear();
}

void SimpleChatClient::receiveMessage()
{
// missing some checks for returns values for the sake of simplicity
qint64 bytes = buffer->write(socket->readAll());
// go back as many bytes as we just wrote so that it can be read
buffer->seek(buffer->pos() - bytes);
// read only full lines, line by line
while (buffer->canReadLine())
{
QString line = buffer->readLine();
chat->append(line.simplified());
}
}

a part of simplechatsever.cpp :


void SimpleChatServer::receiveMessage()
{
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.value(socket);

// missing some checks for returns values for the sake of simplicity
qint64 bytes = buffer->write(socket->readAll());
// go back as many bytes as we just wrote so that it can be read
buffer->seek(buffer->pos() - bytes);
// read only full lines, line by line
while (buffer->canReadLine())
{
QByteArray line = buffer->readLine();
foreach (QTcpSocket* connection, connections)
{
connection->write(line);
}
}
}

I had fix only at these methods And declare quint32 blockSize in the header file.

squidge
23rd January 2011, 20:21
Did you not try to debug your code before posting here?

Eg. does sendMessage transmit a valid message?
Which lines of receiveMessage are actually executed?

Con Nít
24th January 2011, 06:42
i try to debug program and i get some error on "if (socket->bytesAvailable() < blockSize) return; ", i delete it from my source code then sendMessage and receiveMessage run on both server and client, but messenge data not receive, i have just known a little about it, but not mastered yet!

help me ,i really need it :-(( thank in advance .

Con Nít
24th January 2011, 12:45
UP ... help me :-(( i verry need it :-S

wysota
24th January 2011, 12:50
Check what blockSize contains after you stream data to it from the data stream.

By the way, I think the code for the chat needs to be reviewed. Creating a data stream in a slot connected to readyRead() is really a bad idea.