pogostick
24th January 2010, 14:38
Any idea what's wrong with my TCP server-client app? I've been copying the TCP Trip Planner example in the book (so no threads used). The difference is that I've changed it so that it doesn't close the connection after one exchange of data between client/server. It works at first; client sends a request and gets a response, but after that the response is always empty (integers come in as 0 and strings as ""). I've got a feeling there's a simple solution and I'm just doing this wrong.
Here's the code. Well, the relevant part (I hope). Every signal and slot is connected appropriately.
Client:
QTcpSocket tcpSocket;
quint16 nextBlockSize;
quint8 mode;
//constructor
connect(&tcpSocket, SIGNAL(readyRead()), this, SLOT(readServer()));
//connectToServer()
tcpSocket.connectToHost("127.0.0.1", 40567);
nextBlockSize = 0;
mode = 4;
//sendRequest()
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_4);
out << quint16(0) << quint8('S') << mode;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
tcpSocket.write(block);
//readServer()
DataStream in(&tcpSocket);
in.setVersion(QDataStream::Qt_4_4);
for(;;)
{
if(nextBlockSize == 0)
{
if(tcpSocket.bytesAvailable() < sizeof(quint16))
break;
in >> nextBlockSize;
}
if(nextBlockSize == 0xFFFF)
{
//closeConnection();
break;
}
if(tcpSocket.bytesAvailable() < nextBlockSize)
break;
quint8 modev;
in >> modev;
switch(modev)
{
case 4:
//stuff
break;
}
nextBlockSize = 0;
}
Server side (after creating a new object to handle the connection with the client):
//reading and writing
QDataStream in(this);
in.setVersion(QDataStream::Qt_4_4);
if(nextBlockSize == 0)
{
if(bytesAvailable() < sizeof(quint16))
return;
in >> nextBlockSize;
}
if(bytesAvailable() < nextBlockSize)
return;
quint8 requestType;
quint8 mode;
in >> requestType;
if(requestType == 'S')
{
in >> mode;
if(mode == 4)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_4);
out << quint16(0) << mode;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
write(block);
}
}
nextBlockSize = 0;
Here's the code. Well, the relevant part (I hope). Every signal and slot is connected appropriately.
Client:
QTcpSocket tcpSocket;
quint16 nextBlockSize;
quint8 mode;
//constructor
connect(&tcpSocket, SIGNAL(readyRead()), this, SLOT(readServer()));
//connectToServer()
tcpSocket.connectToHost("127.0.0.1", 40567);
nextBlockSize = 0;
mode = 4;
//sendRequest()
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_4);
out << quint16(0) << quint8('S') << mode;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
tcpSocket.write(block);
//readServer()
DataStream in(&tcpSocket);
in.setVersion(QDataStream::Qt_4_4);
for(;;)
{
if(nextBlockSize == 0)
{
if(tcpSocket.bytesAvailable() < sizeof(quint16))
break;
in >> nextBlockSize;
}
if(nextBlockSize == 0xFFFF)
{
//closeConnection();
break;
}
if(tcpSocket.bytesAvailable() < nextBlockSize)
break;
quint8 modev;
in >> modev;
switch(modev)
{
case 4:
//stuff
break;
}
nextBlockSize = 0;
}
Server side (after creating a new object to handle the connection with the client):
//reading and writing
QDataStream in(this);
in.setVersion(QDataStream::Qt_4_4);
if(nextBlockSize == 0)
{
if(bytesAvailable() < sizeof(quint16))
return;
in >> nextBlockSize;
}
if(bytesAvailable() < nextBlockSize)
return;
quint8 requestType;
quint8 mode;
in >> requestType;
if(requestType == 'S')
{
in >> mode;
if(mode == 4)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_4);
out << quint16(0) << mode;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
write(block);
}
}
nextBlockSize = 0;