jhelovuo / RustDDS

Rust implementation of Data Distribution Service

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Windows sending UDP packet on socket returns "WouldBlock"

sanderkukk opened this issue · comments

Hello,

Using current master branch "c0d159c" First of all everything works well on Linux. On windows compile works well but running causes some warnings that seem to break the messages.

When UDPSocket calls the to_send it does not send the byte amounts sent but instead returns an error that is treated as warning it RustDDS.

[2023-03-21T16:05:21Z WARN rustdds::network::udp_sender] send_to_locator - send_to 239.255.0.1:19900 : Kind(WouldBlock)

I tried disabling firewalls etc. but that did not seem the help the issue.
Have you seen this behaviour before or do you have any ideas where this issue resides?

I have not seen this before, but we really do not test on Windows or even make an active effort to support it at the moment.

Currently, RustDDS uses non-blocking I/O to receive data from the network, but sending is done using blocking socket I/O and operating system buffering only. This means that the RTPS worker thread (DomainParticipant event loop) will block to wait if your application is sending data faster than the sending socket can send it.

It appears that for some reason, on Windows, you are getting the send socket into non-blocking mode. This will then return an error instead of waiting on the socket.send_to() call, if the operating system's send queue for the socket is full.

Possible solutions:

  • change (Windows-specific) socket initialization in UDPSender::new to explicitly set the socket option for blocking mode (as is the Linux default).
  • change your application to publish at a slower rate

Thanks for the quick answer.

What I forgot to mention in the initial post was that I tested setting forcefully the .set_nonblocking() and that did not seem to help.

When roaming in the socket creation and especially the windows part it seemed to have a lot of duplicate code and different behaviour. For example the linux section filters out localhost but the windows loop does not. This seems not to have any meaningful impact besides errors at starting RustDDS.

I will investigate more and if a solution is found and if needed I will start a PR.

Couple of more notices:

  1. IPV6 atleast now is currently not supported, is it fine to also filter out IPV6 intefaces when selecting where to bind?
  2. Besides binding to all interfaces/ips allow user to specify which interface to bind.

Thanks for the quick answer.

What I forgot to mention in the initial post was that I tested setting forcefully the .set_nonblocking() and that did not seem to help.

Ah, I see. That is why you get the WouldBlock error.

When roaming in the socket creation and especially the windows part it seemed to have a lot of duplicate code and different behaviour. For example the linux section filters out localhost but the windows loop does not. This seems not to have any meaningful impact besides errors at starting RustDDS.

Your observations may be correct. I have not done the Windows support, or even tested it, so I cannot say much about that. On Linux, the localhost interface is filtered out, because RTPS wants to use IP Multicast, and Linux localhost does not support that. If Windows local loopback interface supports multicast, then that should be used too.

Couple of more notices:

  1. IPV6 at least now is currently not supported, is it fine to also filter out IPV6 interfaces when selecting where to bind?

Yes. Alternatively, you could implement IPv6 support, if you like. RTPS should support that.

  1. Besides binding to all interfaces/ips allow user to specify which interface to bind.

That would be a new feature, and would require a new constructor parameter for DomainParticipant, but if you decide to implement that, then a PR is welcome.

Okay,
To add to my misleading comment I set .set_nonblocking(false).
Played ball with @ebakoba. He got further and got rid of the problem by replacing the socket provider from Mio to std. #251 . I have not tested it with my usage but will soon.

Hello again,

I tested the #251 and this resolved my issues. Just in case tried with both linux and windows and atleast for me it seems everything is working as expected.