Hi,

I have written a server/client, initially using the Fortune examples. The data received is a QVariant - so the QVariant type can be used to determine what to do with the data.

Apologies if my explanations are not great - I am not great with describing what I want to do/have done in programming-speak.

For e.g. a QString it works fine (I guess as it comes in one block?). however attempting with a QImage -> the version/description/data type are sent OK --> If I output the emit_message in read_client then it outputs these OK. I assume this is because the images are larger and need to be sent in multiple blocks. Hence I believe the readClient() would be called multiple times for the same serialized data item. I can't work out how to deal with this gracefully - should I create some function to deal with whether this is a fresh readClient() or one to deal with data that is mid-transmission?
Either that, or I need some sort of loop based on data/the size sent in the header, to build up "data" from the blocks/packets received but am unsure of how to go about doing this. I also send an end of data flag - could this also be used? I have looked through the forums - there are multiple issues on this topic, but I could not find a specific answer (well not with the search terms I have been using)...

Any help would be much appreciated (as well as any pointers if my code is poor -> I am a bit of a QT noob)..

Here is a stripped down version of the codes.

Server:
Qt Code:
  1. void Server::incomingConnection(int socketId) {
  2. ServerSocket *socket = new ServerSocket(this);
  3. socket->setSocketDescriptor(socketId);
  4. }
  5.  
  6.  
  7. ServerSocket::ServerSocket(QObject *parent) : QTcpSocket(parent)
  8. {
  9. connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));
  10. connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
  11. blockSize = 0;
  12. }
  13.  
  14. void ServerSocket::readClient()
  15. {
  16. QDataStream in(this);
  17. in.setVersion(QDataStream::Qt_4_5);
  18. if (blockSize == 0) {
  19. if (bytesAvailable() < (sizeof(quint16)))
  20. return;
  21. in >> blockSize;
  22. }
  23. if (bytesAvailable() < (quint16)(blockSize + sizeof(quint16) + sizeof(quint8)))
  24. return;
  25. quint8 version;
  26. QString description;
  27. QVariant data;
  28. quint16 endFlag;
  29. in >> version;
  30. in >> description;
  31. in >> data;
  32. in >> endFlag;
  33.  
  34. QString emit_message = "\n\tVersion: " + QString::number(version) +
  35. "\n\tType(" + QString(data.typeName()) + "): " + QString::number(data.type()) +
  36. "\n\tSize: " + QString::number(blockSize) +
  37. "\n\tMessage: " + description +
  38. "\n\tData: " + data.toString() +
  39. "\n\tEndFlag: " + QString::number(endFlag);
  40.  
  41. }
To copy to clipboard, switch view to plain text mode 


client:
Qt Code:
  1. //this is fired on the click of a QPushButton
  2. void Client::sendRequest()
  3. {
  4. QTcpSocket socket;
  5. socket.connectToHost(serverName, serverPort);
  6.  
  7. if (!socket.waitForConnected(TIMEOUT)) {
  8. emit error(socket.error(), socket.errorString());
  9. return;
  10. }
  11.  
  12. QVariant data;
  13. QString description;
  14. //text is set in a QLineEdit
  15. if (text == "image") {
  16. data = QImage("someimage.jpg");
  17. description = "This is an image";
  18. }
  19. else {
  20. data = text;
  21. description = "This is some text";
  22. }
  23.  
  24. QByteArray block;
  25. QDataStream out(&block, QIODevice::WriteOnly);
  26. out.setVersion(QDataStream::Qt_4_5);
  27. out << quint16(0) << quint8(1) << description << data << quint16(0xFFFF);
  28. out.device()->seek(0);
  29. out << (quint16)(block.size() - sizeof(quint16) - sizeof(quint8) - sizeof(quint16));
  30. socket.write(block);
  31. socket.flush();
  32. qDebug() << "Sending: [" + description + data.toString()
  33. + "] to server(" + serverName + ":" + QString::number(serverPort) + ")";
  34. }
To copy to clipboard, switch view to plain text mode 

Thanks,

James