On 3/24/2021 5:18 AM, Kristian Ivarsson via Cygwin wrote:
Hi Glenn
Thanks for the reply, so more below
Hi all
Using AF_UNIX/SOCK_DGRAM with current version (3.2.0) seems to drop messages
or at least they are not received in the same order they are sent
Attached C:ish (with C++ threads though) sample program that essentially creates a
"client" that writes as much as possible and a "server" that consumes as much
as possible
It seems like some buffer is filled and then messages are dropped (or at least it appears
so) (if someone is about to test this, the "sleep" might need to be adjusted in
order to make this happen)
Hopefully it's just a flaw in our application (and sample), but as far as we
can see, this should work
Does anyone, perhaps named Ken, have any insightful thoughts about this ?
const int size = BUFSIZ * 2;
char buffer[size] = {};
for( int idx = 0; idx < count; ++idx)
{
memcpy( buffer, &idx, sizeof idx);
const ssize_t result = sendto( fd, buffer, size, 0, (struct
sockaddr*)&address, sizeof address);
const ssize_t result = recv( fd, buffer, size, 0);
...
int index = 0;
memcpy( &index, buffer, sizeof idx);
This appears to be a programming error, unrelated to Cygwin.
I know that what you provided was an example test case, but you might want to
check if your app is sending way too much when the actual payload size is much
smaller. In the example you provided, you are sending 16KB instead of 4 bytes
for the count.
To send a larger buffer (in this case 16 KB) is intentional, but just the
sizeof int is relevant. The reason is just to send many bytes and verify that
they end up on the other side in correct order
Is your code handling partial read/recv and partial write/sendto? (It is
definitely a bug in the use of recv() in the sample code.)
It was not and the updated version does not either, but that is not the issue
though but I added a test to verify that the whole chunk is sent/read
Partial reads and writes can occur more frequently with non-blocking sockets,
but it is still good defensive programming to detect and handle partial
read/writes.
That might be the case, but this is blocking attempts though (or maybe I've
misunderstood the flags ?), but regardless of that, the test-case is not about
how to handle partial writes/reads though, but to kind of show that messages
seems to be lost, but of cource code need not to be flawed so thanx for the
feedback
It almost seems like it is UDP-semantics and that packages can get lost or end up in non
sequential order, and of course SOCK_DGRAM tells you that, but the posix description says
"UNIX domain datagram sockets are always reliable and don't reorder datagrams"
It seems like when an internal buffer or so of 64 KB is filled the rest of the packages are
dropped until consumed, so in this case the 32 first packages arrive in correct order but
after that any random package (with index > 32) seems to end up at the "server"
It goes without saying that if your protocol sends a fixed size chunk of data,
that you should ensure that you read the entire fixed size, even if only using
part of the data.
That's done in the updated version, or at least verified
Thanks for the test case. I can confirm the problem. I'm not familiar enough
with the current AF_UNIX implementation to debug this easily. I'd rather spend
my time on the new implementation (on the topic/af_unix branch). It turns out
that your test case fails there too, but in a completely different way, due to a
bug in sendto for datagrams. I'll see if I can fix that bug and then try again.
Ken
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple