using boost::asio to asynchronous read from multiple ports - boost-asio

Is it possible to receive packets asynchronously from multiple ports using boost::asio or we have to use different instances? can we do it using single thread? any link/sample code would be helpful. I want to read from UDP ports.
I create my socket connection using socket(PF_INET, SOCK_DGRAM, 0);.

Related

Can IPv6 multicasting work when one or more receivers are unable to bind to the program's well-known port?

Consider a simple IPv6 multicast application:
A "talker" program periodically sends out IPv6 UDP packets to a well-known multicast-group, sending them to a well-known port.
Zero or more "listener" programs bind themselves to that well-known port and join the well-known multicast group, and they all receive the UDP packets.
That all works pretty well, except in the case where one or more of the listener-programs is unable to bind to the well-known UDP port because a socket in some other (unrelated) program has already bound to that UDP port (and didn't set the SO_REUSEADDR and/or SO_REUSEPORT options to allow it to be shared with anyone else). AFAICT in that case, the listener program is simply out of luck, there is nothing it can do to receive the multicast data, short of asking the user to terminate the interfering program in order to free up the port.
Or is there? For example, is there some technique or approach that would allow a multicast listener to receive all the incoming multicast packets for a given multicast-group, regardless of which UDP port they are being sent to?
If you want to receive all multicast traffic regardless of port, you'd need to use raw sockets to get the complete IP datagram. You could then directly inspect the IP header, check if it's using UDP, then check the UDP header before reading the application layer data. Note that methods of doing this are OS specific and typically require administrative privileges.
Regarding SO_REUSEADDR and SO_REUSEPORT, apps that do this will allow multiple programs to receive multicast packets sent to a given port. However, if you also need to receive unicast packets this method has issues. Incoming unicast packets may be set to both sockets, may always be sent to one specific socket, or sent to each in an alternating fashion. This also differs based on the OS.

Cannot receive UDP when different sockets bind to same port

Came across an interesting observation in a SO post, where there are two client processes (client is across NAT) which both bind locally to same port (reusing port), use UDP socket to send data in one process, and receive in another.
It turns out, the receive process could not receive the data.
Client Process (Send) --- Port 5000 ---> NAT --Port 5333 (say) -> Server
This works
Server ----Port(5333)---> NAT ---Port??---> Client Process (Recv)
This doesnt work
It seems if a single client process with same socket is used for both send and receive, it receives the data from server.
Why this behavior? If both client send and receive processes were bind to the same port, things should have worked?
Why is different process causing this behavior? Looks like due to different processes, different port are used despite port reuse?

Is TCP better than UDP for multi-threaded servers?

If I was to implement a server to handle multiple clients connecting simultaneously would it be better to use TCP?
Not taking efficiency into account (I know know UDP is quicker, but unreliable).
In UDP you can't have sockets for each client connection?
Because in UDP the socket is identified by only the destination port number (right?).
In Java, I know it is easy to create a multi-threaded server to handle multiple clients at the same time in TCP. But can it be done in UDP? I imagine that it would be very complicated.
I'm just trying to get an understanding of UDP here (I don't want to actually implement anything).
It depends on what kind of server you are developing. If you need your clients to stay connected and ready to receive data from server(for example a push service) you should implement it using TCP. If you want to implement a simple request-response service, then UDP is better choice.

Is it possible to thread pool IMAP connections?

From what I understand IMAP requires a connection per each user. I'm writing an IMAP client (currently just gmail) that supports many (100s, 1000s maybe 10000s+) users at a time. Obviously cutting down the number of open connections would be great. I'm wondering if it's possible to use thread pooling on my side to connect to gmail via IMAP or if that simply isn't supported by the IMAP protocol.
IMAP typically uses SSL over TCP/IP. And a TCP/IP connection will need to be maintained per IMAP client connection, meaning that there will be many simultaneous open connections.
These multiple simultaneous connections can easily be maintained in a non-threaded (single thread) implementation without affecting the state of the TCP connections. You'll have to have some sort of a flow concept per IMAP TCP/IP connection, and store all of the flows in a container (a c++ STL map for instance) using the TCP/IP five-tuple (or socketFd) as a key. For each data packet received, lookup the flow and handle the packet accordingly. There is nothing about this approach that will affect the TCP nor IMAP connections.
Considering that this will work in a single-thread environment, adding a thread pool will only increase the throughput of the application, since you can handle data packets for several flows simultaneously (assuming its a multi-core CPU) You will just need to make sure that 2 threads dont handle data packets for the same flow at the same time, which could cause the packets to be handled out of order. An approach could be to have a group of flows per thread, maybe using IP pools or something similar.

How to find a locally available UDP port with unix Sockets API

I have an application where I have potentially many processes must send a message to one process. I figured the most expedient way to do this would be to just send a UDP datagram.
When opening a socket, I need to specify which port to listen to. As I just want to fire and forget the UDP datagram, I'd like to just have the OS pick an available port. I'd rather not have to hunt for one, especially as many instances of my process may be running. Is there a way I can tell the OS to just pick an available port (or better yet, not even open a listening socket) to fire and forget my UDP datagram?
Yes. Specify 0 as the port. The OS will pick an available port for you.
Answering the "Problem" rather than the "Question"
If all the processes are operating on the same PC, you might want to look into shared files or some other means of communications other than a networking stack.
I'd suggest you explore the options in Boost's Interprocess library
http://www.boost.org/doc/libs/1_37_0/doc/html/interprocess.html
Quick guide here:
http://www.boost.org/doc/libs/1_37_0/doc/html/interprocess/quick_guide.html
Specifically, I suggest you use a named pipe or shared memory between your processes.