Better have one long or multiple short UDP sockets? - c

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.

Related

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.

socket control to accept multiple UDP connections

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

Is multithreading required when client and server want to talk at the same time?

I have two questions regarding using sockets for client server communication. Assume there is only 1 client in both the cases.
1) I know that we can send and receive data between client and server using a single socket. But in that case, what will happen when both the server and the client try to send the data at the same time?
2) Which of these is the best model?
i) Using single thread, single socket for sending and receiving
ii) Using 2 threads(one for sending and one for receiving), single socket
iii) Using 2 sockets and 2 threads, one for sending and one for receiving.
The connection is full-duplex, meaning that sends and receives can happen at the same time. So in answer to question one, both client and server will be able to send/read data from their socket simultaneously.
In terms of which "model" is best, it depends on your application and what you're trying to achieve. Incidentally, you don't need to multi-thread. You could:
Multi-process (fork)
Use non-blocking sockets (select/poll)
Use asynchronous notification (signals)
All of which have pros and cons.
For question number one, nothing special will happen. TCP is fully duplex, both sides of a connection can send simultaneously.
And as there is no problem with sending/receiving simultaneously, the first alternative in your second question is going to be the simplest.
In that scenario you dont need threads. The sockets themselves buffer the incoming data until you read it from the file-descriptor. More precisely there are multiple levels of buffers starting at the hardware. You will not miss data because you were writing at the same time, it just waits for you until you next read from the socket's file-descriptor.
There is no inherent need for multithreading if you want to poll at multiple sockets.
All you really have to do is use select().
To achieve this you define a FD_SET (File-Descriptor Set) to which you add all the sockets you want to poll. This set you hand to select() and it will return you all file descriptors with pending data.
man page for select, fd_set and a select tutorial

Send same info to multiple threads/sockets?

I am writing a server application that simply connects a local serial port to multiple network connected clients. I am using linux and C for the server application because the equipment for the program is a router with limited memory.
I have everything setup for multiple clients to connect and send data to the serial port using a fork() process for each connection.
My problem lies in getting data incoming on the serial port out to the multiple (varing number) client connections. my problem lies in designing a way for each active socket to get all of the incoming data, and to only get it once. Any help?
Sounds like you need a data queue (buffer) for each connected client. Each time data comes in on the port, you post it to the back of each client's queue. The clients then read the data from the front of their respective queues. Since all the clients will probably read at different rates/times, this will ensure all of them get a copy of the data only once, and you won't get hung up waiting for any one client while more data comes in. Of course, you'll need to allocate a certain amount of memory for each connected client's queue (I'm not sure how many clients you're expecting, and you did say your available memory is limited), and you need to consider what to do if a queue gets full before the client reads all of it.
Presumably you keep a list or some other reference of/to connected clients, why not just loop over that for each bit of information and send it to all of them?
A thread per socket design might not be the best way to solve this. An event driven asynchronous approach should be a much better fit. However, if you must do it with threads, and given that serial ports are slow anyway, building a pipe between the thread listening to the serial port and all the threads talking to the network clients is the most practical. You could do fancy things with rwlocks to move the data, but you'll still need a way for the network threads to wait on both the socket and the data from the serial port, so you need to use file descriptors for both and something like poll.
But seriously, this would likely be much easier and would perform better without the threads. Think of it as a main loop which waits on poll which is watching the network and the serial port, determines which event occurred, and distributes data accordingly. It should be easier all around once you get the idea.

Acknowledge UDP Packets without Signals?

I'm implementing a basic file transfer system between a client and server, for practice using UDP. I'm trying to implement some basic reliability.
Right now my server sends a chunk of data, and waits for an acknowledgement signal saying the chunk was received. Is there a way to send a more robust message without the use of signals?
Ideally I'd like to just be able to use sendto and recvfrom, but in the off chance that no packets are received, then recvfrom would just hang.
Is this possible, or do I need to use signals?
You can use select() to learn when there's input to be read from the socket on which you receive ACKs from the client. You can then specify a timeout, after which select() will return even if no input is available. This gives you a chance to keep the server "alive".
You can also use non-blocking I/O, which gives even more flexibility, but is a bit harder since you need to take care not to "busy loop" and consume too much CPU.
Set a socket read timeout with setsockopt() and SO_TIMEOUT.

Resources