Sending from the same UDP socket in multiple threads - linux

I have multiple threads which need to send UDP packets to different IP addresses (only to send, nothing needs to be received). Can I reuse the same UDP socket in all the threads?

Yes, I think you can.
As the packets are sent out individually, although the order they are received will be nondeterministic, it is already with UDP.
So sending in multiple threads in the same socket is fine.
Although, if you're doing other stuff with the socket, such as bind(), close(), then you could end up with race conditions, so you might want to be careful.

System calls are supposed to be atomic, so formally it seems fine for UDP. Then kernels have bugs too and you are inviting all sorts of nasty surprises. Why can't you use socket per thread? It's not like with TCP where you need a connection. As an added bonus you'd get a separate send buffer for each descriptor.

Related

Advantages of multiple udp sockets

Hi this question is from a test i had recently :
(code of a server using one thread for read actions and N number of threads to write where N is the number of Writing actions needed to be done right now)
will using multiple UDP sockets (one for each client )over a single one(one for all of them) have any advantages ?
the official answer :
no because the server is using one thread for read/write per client which wont make it more efficient (students who addressed buffer overflow got full points)
my question is - under any circumstances will changing single UDP to many will have an efficiency impact?
Thanks
Maybe yes, if you are using BSD Systems (OSX, FreeBSD, etc.). BSD System do not behave well when sending a lot of upd packets on the same sockets. If the sending queue of the socket is full, the packets get dropped. So write on udp sockets never blocks on BSD systems. When you use 10.000 UDP Sockets sending to the same address, no packets will be dropped on the sending host. So there is definitely an advantage, since some OSs do crazy queue management.

Epoll for many short living UDP requests

I want to realize an application which handles many UDP connections to different servers simultaneously and non-blocking. They should just send one short message (around 80 bytes including the UDP header) and receive one packet. They are not intended to do more than these two operations: send a message and receive one. So my first goal is to have as many requests per second as possible. I thought of using epoll() to realize my idea, but when I read that epoll is primarily meant for servers with long living client-server sessions, I was unsure if this would make sense in my case. What is the best technique? (I use Linux)

Reusing a port number in a UDP

In ASIO, s it possible to create another socket that has the same source port as another socket?
My UDP server application is calling receive_from using port 3000. It passes the packet
off to a worker thread which will send the response (currently using a dynamic source port).
The socket in the other thread is created like this:
udp::socket sock2(io_service, udp::endpoint(udp::v4(), 0));
And responds to the original request using the sender_endpoint saved with the original packet.
What I'd like to be able to do is respond to the client using the same source port as the server is listening on. But I can't see how that can be done. I get an exception if I try that saying address in use. Is it possible to do what I'm asking? The reason I want that is if I use dynamic ports, it means the clients need to add special firewall rules in windows to allow the reply packets to be read. I've found that if the source port is the same in the reply, windows firewall will allow it to pass back in.
The exception tells you as it is: you can't create two live sockets with the same source port. I don't know ASIO, but you should be able to create the socket before spinning off the thread, keeping reference to the socket and the thread for later use, and once the data sending thread is idle, joining back to it and sending any other stuff.
EDIT: with a little bit of effort, you can also make a socket for which you don't have to wait until the entire data from one thread has been sent: have a worker thread owning the socket listen on a queue for chunks of data (ideally exactly the size of the payload you intend to send) and send arbitrary chunks of payload to this queue, from multiple threads.
You should be able to use the SO_REUSEADDR socket option to bind multiple sockets to the same address. But having said that, you don't want to do this because it's not specified which socket will receive incoming data on that port (you would have to check all sockets for incoming data)
The better option is just to use the same socket to send replies - this can safely be done from multiple threads without any additional synchronisation (as you are using UDP).
send reply to the same socket (that you received client's request on) instead of creating new one
but make sure you don't send to the same socket from both threads simultaneously

Socket fd in multithreading

Is it ok to use same socket fd in multiple threads ? (over linux)
It depends on what you expect to happen, but yes you can. If you are reading UDP packets that are each a complete message this can work well. If you are reading data streams from TCP this will probably not work well.
You can have multiple threads accepting incoming connections on a socket and that can work pretty well as each thread gets one connection.
You will run into concurrency problems trying to send() or recv() (SOCK_STREAM) from multiple threads. You should use a critical section or some other means of creating serial access to send() and recv().
One standard thing to do with threads is to have the master listen() & accept(), then pass off the socket to a client thread that sends/receives/processes from that one socket. The client thread is responsible for calling close() or shutdown().

Forking with a listening socket

I'd like to make sure about the correctness of the way I try to use accept() on a socket.
I know that in Linux it's safe to listen() on a socket, fork() N children and then recv() the packets in all of them without any synchronisation from the user side (the packets get more or less load-balanced between the children). But that's UDP.
Does the same property hold for TCP and listen(), fork(), accept()? Can I just assume that it's ok to accept on a shared socket created by the parent, even when other children do the same? Is POSIX, BSD sockets or any other standard defining it somewhere?
If you fork() and then accept() in your children only one child process is going to call accept() on a connection and then process it. This is pre-forking and the connections won't be shared among the children.
You can do a standard one child per connection scheme by reversing the order and accepting and forking. However both of these techniques are for efficiency, balancing, etc., not for sharing a particular connection.
TCP is different from UDP. It would be inadvisable to do that in TCP as you will almost certainly end up with a mess. A given received message can be spread over one or more packets and it would be more of a pain for multiple process to coordinate than would be to have one child handle the connection.

Resources