QLocalSocket: Send data that large 4096 bytes
-
Hi everyone
I have client and server application (that used QLocalSocket and QLocalServer)Client loaded image, resize and send to the server (after resize image has 700 ~ 800 Kb size)
Server received image and save to DB.When client sended one image, server received 2 messages:
- First message has 4096 Bytes size
- Second message has Image.Size() - 4096
Can you tell me why server received 2 messages? And how can fix it (1 message)?
Additional info:
readBufferSize = 0
Image has size from 100 Kb to 1000 Kb -
Hi,
Because there's no guarantee that your data will be sent in one go. That's the nature of TCP. When sending data it can be split in several messages. It's up to you to ensure that everything has arrived.
-
Thank you for reply!
And how can I merge data that be splitted? -
Have a look at the Fortune client example and Fortune server example
-
This examples works with TCP (QTcpServer and QTcpSocket)
I'm used QLocalServer and QLocalHost that use Named Pipes on Windows. Named Pipes is not a TCPI found this answer on stackoverflow:
problem solved. Actually there was delay in writting and reading data chunks and whenever in case server has written let say 4000 bytes and on the other side client is busy processing that data. at the end of 4000 bytes processed, there may be some bytes left let say it may be 4 bytes left which may belong to next packet which does not come on socket yet and system is in while loop. now i am exiting from while and reading that 4 bytes by appending next at the start of next chunk.
But I use readyRead signal and signal emitted when all data sended
-
You can find the same examples under Local Fortune server/client. You'll see the implementation is pretty much the same as the TCP counterparts
-
TCP (and UDP) is stream base, there is no start or end. TCP receive messages in send order. UDP don't.
Assuming TCP.
So using TCP you know that received messages is in send order. If client sends image data server will receive that data. Now one problem remains - how to know if client send whole data? There is several ways. Simplest one would be to close connection by client when whole data is send. So receiving side would save image data to DB when client disconnect. Better approach is to implement message format.This can be achieved by pre-appending size of send data. Both sides must know "format" of message, so it could be something like this:
[message size][message data]
, then on receiver side size is read and parsed, because by design format of message was decided so receiver knows that i.e. 4bytes of first received message (when connections is initialized and first message is received) contains message size, then receiver parse that infromation and create buffer to hold all data (or write directly do output device). If messages comes one after another then situation can be like this:
[previous end message data][new message size][new message data]
but receiver already knows previous message size, so if currently received message data, plus what is already received, extend expected message size then receiver knows that current message contains previous data plus some new data.
Depending on message size situation can be like this:
[message 1 size][message 1 data][message 2 size][message 2 data]...
Receiving part must implement receiving parser, so actual data can be parsed out.
Socket is QIODevice and when something can be read from device readyRead() signal is emited. That's why it doesn't matter how it's implemented on OS side because QTCPSocket and QIODevice will work in same way. Plus, with is important, currently available data don't need to be whole data. readyRead() just inform that there is something to read.
And question: if You are using QLocalServer and QLocalHost that means You are just sending data to some DB app, why to use sockets for this? Why not to use: QSharedMemory and You don't need to worry about message formatting.
-
@LuGRU
Why not to use: QSharedMemory and You don't need to worry about message formatting.
Because I run process with different account.
First process run from System account and second from local accountWhen I read SharedMemory in another process I have error "QSharedMemory handle doesn't exist"