I am sending some data with a socket write() function. I am actually using QT, and specifically writing using the underlying qint64 QIODevice::write(const QByteArray &byteArray) function but the question could be applicable for C as well.
qint64 QIODevice::write(const QByteArray &byteArray) is implemented as:
inline qint64 write(const QByteArray &data)
{ return write(data.constData(), data.size()); }
The code looks something like below:
// Function, send data once per second using a timer
void sendData()
{
...
...
// Create const QByteArray packet1, 100 bytes
socket->write(packet1); // packet1 is a const Byte Array
socket->flush();
// Create const QByteArray packet2, 1200 bytes
socket->write(packet2); // packet2 is a const Byte Array
socket->flush();
// Create const QByteArray packet3, 1200 bytes
socket->write(packet3); // packet3 is a const Byte Array
socket->flush();
return;
}
Everything works okay, but about 2 to 3 times day, some of the packet data (in the data header) gets garbled. I.e. 2 or 3 packets show up garbled over a 24 hour day. This data is constant and is not modified. I am wondering whether something is at play here.
I am curious - Am I sending the data too fast. Using the waitForBytesWritten() is the alternative to flush(), and I am more interested in pinpointing what is going on.
Would it be wiser to insert a small sleep between the sends so that Ethernet Interpacket Gap (IPG) is respected, or would that be too crude?
From your comment:
Over a 24 hour period the receiver gets 2 or 3 messages with a garbled message header. Thus the messages do have an application layer protocol. Most of the messages get through (something like 86397 of them, while 3 are bad) ...
If you are really sure that this the messages actually arrive garbled and that there is no programming error in your application instead, then you should have a look at the error rate of the link. TCP contains a checksum but this will not detect every possible error. But for every garbled packet where the errors got not detected there should be a lot of packets with detected errors. This means when analyzing the link for errors you should find a lot of detected errors.
Would it be wiser to insert a small sleep between the sends so that Ethernet Interpacket Gap (IPG) is respected, or would that be too crude?
This should not be necessary at all for normal connections. If you have a link with a high error rate it might or might not help depending of where the errors come from, but I would not expect it to help in most cases. It would be more useful instead to fix whatever unreliable equipment you have there. Note that such errors might also be introduced on the sender or recipient hardware. Therefore it might be useful to try to replace this hardware too.
It can also be useful to have some better error detection at your application level. Using TLS instead of simple TCP not only provides encryption but also provides a much better detection of transmission errors than plain TCP. Instead of having this detection at the application level you can also have a better error detection and handling at the network layer by using a VPN like IPSec over the existing unreliable link.