socket control to accept multiple UDP connections - c

I'm breaking my mind trying to understand how make a client/server write by myself accept multiple socket connections.
The connection is a datagram (UDP), for now was implemented based on getaddrinfo(3) man page works nice, but each client needs to wait the process of early connections be processed.
I've heard about select, but in its man page says:
select() can be used to solve many problems in a
portable and efficient way that naive programmers try to solve in a
more complicated manner using threads, forking, IPCs, signals, memory
sharing, and so on.
and more:
The Linux-specific epoll(7) API provides an interface that is
more
efficient than select(2) and poll(2) when monitoring large numbers of
file descriptors.
So, it is? epoll is simply better than select? Or it depends? If it depends, on what?
epoll man pages has a partial sample, so I'm trying to understand it.
At now, (on server) I think, I need a thread to listen in a thread and write in another. But how to control the completion of a partial message? If two clients send a partial message interleaved, how to identify? By the sockaddr? if it's the only need, I can manage it without a pool, so why use a epoll?
Can anyone try to explain to me, how to make, or where to learn about a multi-connection client-server UDP app?

I think there is a misunderstanding here about UDP. UDP is not a connection oriented protocol which means there is no permanent connection like TCP. UDP just bind to an address/port and waits for packets from everyone. At the server there is only one socket listening per address/port number. When a packet is received you may find out who is the sender by the packet's source IP, you can reply to the sender thru this IP.
As I see it, there is no need for poll() o select() you bind to an address/port and asynchronously receive packets. That is, when a packet is received you get a signal/message alerting your asynchronous function. This function should be reentrant, it means that in the middle of a reception another signal could be received and care must be taken when accessing/modifying global stuff (variables/objects). When dealing with an incoming packet it should be processed as soon as possible or, in case the process takes too long, you better keep the packet in a packet spool and process them in another [less priority] thread.
For UDP packet size read this question.
For UDP fragmentation read this
For UDP packet header read this

Related

Synchronizing between UDP and TCP

I'm currently implementing a daemon server that acts as 2 servers. One of the servers is recieving logs via UDP from a collection of producers. The second server is broadcasting every log that was received from a producer to a consumer who is currently connected via TCP.
These are 2 separte sockets. My current(pretty basic) implementation is to use select() on these 2 sockets, and handle every read signal accordingly, so my code is basicly(NOTE this is pseudo code)
for(;;) {
FDSET(consumers_server)
FDSET(producers_server)
select()
if consumers_server is set:
add new client to the consumers array
if producers server is set:
broadcast the log to every consumer in the array
}
This works just fine, the problem ocurres when this code is put in to stress. When multiple produers are sending logs(UDP) the real bottleneck here is the consumers which are TCP. Sending a log to the consumers can result in blocking, which i can't afford.
I've tried using non-blocking sockets and select()ing the consumers write fds, the problem is this would result in saving the non-sent logs in a buffer, until they can be sent. This results in a very unelegant massive code, and the system is also low on resources(mainly RAM)
I'm running on a linux distro.
An alternative approach to synchronize between these UDP and TCP connections would be welcomed.
This is doomed to failure. Sooner or later you will be unable to send to the TCP consumer. Whether that manifests itself as blocking or EAGAIN/EWOULDBLOCK isn't really relevant to the underlying problem, which is that the producer is overrunning the consumer. You have to decide what to do about that. You can have a certain amount of internal buffering but at some point you will have to stop reading from the UDP producers. At that point, UDP datagrams will be dropped and your system will lose data, and of course it is liable to lose data anyway by virtue of using UDP.
Don't do this. Use TCP for the producers: or else just accept the data loss and use blocking mode. Non-blocking mode only moves the problem slightly and complicates your code.

Reading multiple UDP messages without polling

I would like to use the recvmmsg call to read multiple UDP messages from ONE single socket at once. I'm reading data from a single multicast group.
When I read TCP data, I usually use poll/select with a non-blocking socket (and timeout) to be notified when that is ready to be read. I follow this approach as I am aware of the issue of spurious wakeup and potential troubles of having a blocking socket.
As my application must be very quick, if I follow the same approach with recvmmsg I will introduce an extra system call (poll/select) that might slow down the execution.
So my two questions are the following:
With UDP, can I safely read from BLOCKING sockets using recvmmsg without poll/select or do I have to apply the same principle I've used for TCP (non-blocking+poll)?
Suppose I have a huge amount of multicast traffic, would you go for non-blocking socket + recvmmsg only (no poll) and burn a lot of CPU?
I am using Linux: CentOS 7 and Oracle Linux.
You can always use blocking mode, with both TCP and UDP sockets.
If you want to impose a read timeout there is setsockopt() with the SO_RCVTIMEO option.
I follow this approach as I am aware of the issue of spurious wakeup
What spurious wakeup? Never seen it in 25 years of network programming.
and potential troubles of having a blocking socket.
Never heard of those either.
Using select() and non-blocking mode with a single socket is pointless unless your platform doesn't support SO_RCVTIMEO. It's an extra system call, for a start.
The option of using blocking or non-blocking depends on what is the final purpose of the application.
- Say it's just a sample chat application showing the usage of UDP combined with TCP then you can use either.
- But if you are planning to make this module a part of highly used application with lots of data flowing then probably creating multiple threads/processes to handle different tasks will come in handy. The parent thread will to wait for the message but for processing it will spawn a different child thread and hence make the parent available for the next message.
But in a nutshell I don't see any issue with your first option of using a blocking socket without poll/select for a UDP application considering it's just for homework purposes.

select() issue with a push server - c/c++

I'm writing a server in C ++ for both Windows and Unix systems.
A key feature of this server is that it must be able to receive and send network packets at any time.
Specifically, the server must be able to send data to the client not only in response to their messages, but also be able to send packets to them asynch in push.
I'm having difficulty in implementing a solution that uses the select() function in the scenario described above.
The solution I have currently implemented does not convince me at all and I think it can be implemented with better patterns/solutions.
I currently have a dedicated thread (selector) that performs the select by listening on events in the reading for the server socket (to accept new connections) and for the sockets connected to the server.
This is the main select() loop:
if((sel_res_ = select(nfds_+1, &read_FDs_, NULL, &excep_FDs_, &sel_timeout)) > 0){
if(FD_ISSET(serv_socket, &read_FDs_)){
//we have to handle a newly connection.
...
if(sel_res_ > 1){
//in addition to the newly connection, there is also some other message incoming on client sockets.
...
}
}else{
//we have to handle incoming messages on client sockets
...
}
}
This solution works well for receiving the data and to respond to client requests in synchronous form.
However, the server must also be able to send asynchronous data, and send when necessary, packets in push.
To do this I currently use separate threads that perform directly the send() on the client sockets.
This solution does not convince me, and I would like to centralize the packets receiving and sending on the selector thread.
The main difficulty is that the select() by its nature is blocking and I have no control until a client does not send any packet or the timeout is triggered.
The solution to set a timeout very low does not convince me; I see it as an easy solution that is actually doing active wait, and not only, however, the worst case I would pay the price of the timeout before sending the push packet.
I thought a more 'elegant' solution; I think, will work well, but only for a Unix/Linux platform.
I thought to use an anonymous pipe and insert into the select() read_FDs_ the anonymous pipe read descriptor.
In this way, when a thread wants to send a data in push, it writes something on this pipe, interrupting the select() and returning control to the selector that can then predispose to send the data to the client, without significant loss of time.
I think that this solution, unfortunately, cannot be implemented on Windows because the select() function on that system works only with fds that are actually sockets.
So the question is: Is there some well known solution that can be used to address this kind of scenario (both Linux and Windows)?
You can create a self connected UDP socket, this works equally well on Windows and Linux.
Basically, you create a UDP socket, bind() it to INADDR_LOOPBACK and port 0, and connect() it to itself (with the address taken from getsockname()).
At this point, you can send yourself a single byte message (or something more specific) to wake yourself up.

Will a disconnected udp socket still receive traffic from a port that another socket is connected to?

I'm trying to write a server/client pair to run over udp, and the only way i've been able to get it going is having the server aware of the client's ip and port before the connection starts. My new design involves waiting for a packet to come in, recording the sender address, forking to a child process (the parent loops around and continues listening), which then connect's to the client the transmitted the packet. The child should then only receive packets from the associated client, but the documentation is unclear is the parent socket will continue receive traffic from that client. I'm working on a program to try it, but i figured i could ask the question at the same time.
EDIT: It seems that when the child's socket is connected'd it will connect the parent's socket too.
UDP protocol does not operate connections, it's a connection-less protocol. It is enough for one side to listen and other side to just send datagrams for data channel to work.
On the question (sorry, didn't got the point before): forking is not the way out when working with UDP. Connection-based protocols are widely used with that technique. That is possible because:
you can fork right after listen()
the first process accepts connection works with it (and only that process posesses the newly created connected socket.
When you work with UDP you don't have such gap (as before accept() with TCP) to know when exactly to fork (especially when you have intensive datagram flow).
So, when you design UDP service, you need either
use non-blocking I/O with event loop or
design threaded solution.

Better have one long or multiple short UDP sockets?

I want to send regularly UDP messages through sockets.
Is it better to use one socket, or to recreate a socket for each message and close them just after?
Since UDP is stateless, does it even change anything?
If you're expecting to receive anything over the socket, it had better exist for the entire time over which you're expecting to receive.
If you're expecting to send multiple messages without receiving any replies you already have a design mistake, but there doesn't seem to be a good reason why you would keep opening and closing UDP sockets for that purpose. Surely it makes more sense to keep the socket open as long as necessary?
Since UDP is a packet-oriented protocol, there is no "connection" to open or to close. If you are going to send a lot of messages to a particular address you can call connect on a UDP socket, and then use send and recv to communicate instead of sendto and recvfrom. This way you don't have to specify the address where you want the data sent on every function call, but that doesn't mean that a connection is established.
So, whether it's better to create one socket and reuse it, or create a new one every time, depends more on your programming style: If you create lots of sockets and store them for long periods of time without using them, you may eventually run out of sockets. Then again, asking the operating system to create new sockets frequently may become a performance bottleneck if you do it in a tight loop.

Resources