I need to find a solution for high throughput network data interleaving in my QT framework based windows application.
My application is based on server/client architecture. The client connects to a server and both can exchange messages of arbitrary sizes. A message is just a piece of data, with a header describing the message.
The following limitations must be considered:
- Message size is known in advance on sender site (on receiver site after receiving first message header)
- There is only one network stream (one opened port)
- Connection oriented protocol (TCP/IP) if possible
- Wireless network connection (WLAN) (typically 5-10 MB/s net throughput)
- Messages should be sent as fast as possible
- Large messages may not block smaller messages
Because there can only be one data stream (per connection), I decided to use data interleaving so that one large message can not block several smaller messages. For this purpose I allow message fragmentation and introduced a 3 class message priority. The message header contains the total size, payload offset and payload size so that assembling of an interleaved message is possible on receiver site.
Example of large messages:
- Video stream
- Firmware update
Examples of small messages:
- Status messages (workload, battery status, ...)
- Command messages
A naive approach would be to send away all the messages in a row. However this would block smaller high priority messages for certain amount of time because video stream data messages for example utilizes the network connection to the full. This would not be acceptable. Instead of sending a message in one part, I decided to split it and interleave them in 8 KB large chunks. Although I have no good idea how I can optimally interleave the individual message fragments into one another, I think there are several sheduling strategies that can be used here. However, this is not my problem.
Guess, at a certain point in time, there is a single very large message that has to be sent. There is no other message in output queue! So there is nothing to interleave here. A naive approach would be to send that message away. However guess, shortly after beginning to send this large message, several high priority small messages gets queued. However since the large message was already sent to the socket, these new small messages has to wait until the large message has been sent. This case should be prevented!
I had many different ideas, but none of them was satisfactory.
One idea was to provide only just so much data on the socket that it does not run out of data, but not so much that too many data is in the socket buffer. This would ensure that at any time smaller data can be inserted into the data stream without major delays. The problem is, how can I find out how much data is optimal so that the throughput is still at maximum? How can I get informed that data has been sent and how much data is left in socket buffer?
Did I miss something? Is there even a better solution? I'm open for new/better ideas.
Aucun commentaire:
Enregistrer un commentaire