0

I am new to Linux socket programming. Here I have an basic question:

for UDP, why we need select()?

  1. As UDP is stateless, so UDP server just handles whatever data it received. There will be no new socket created once a new client sends data, right?

  2. if so, select() will be returned/notified once this socket has data arrived. So we don't need to go throughput all to check which socket is being notified (as there will be only one socket);

  3. Is this true? non-blocking UDP socket + select() == blocking UDP socket.

Thanks!

Howard Shane
  • 926
  • 13
  • 28

1 Answers1

6

The main benefit of select() is to be able to wait for input on multiple descriptors at once. So when you have multiple UDP sockets open, you put them all into the fd_set, call select(), and it will return when a packet is received on any of them. And it returns an fd_set that indicates which ones have data available. You can also use it to wait for data from the network while also waiting for input from the user's terminal. Or you can handle both UDP and TCP connections in a single server (e.g. DNS servers can be accessed using either TCP or UDP).

If you don't use select(), you would have to write a loop that continuously performs a non-blocking read on each socket. This is not as efficient, since it will spend lots of time performing unnecessary system calls (imagine a server that only gets one request a day, yet is continually calling recv() all day).

Your question seems to assume that the server can work with just one UDP socket. However, if the server has multiple IP addresses, it may need multiple sockets. UDP clients generally expect the response to come from the same IP they sent the request to. The standard socket API doesn't provide a way to know which IP the request was sent to, or to set the source address of the outgoing reply. So the common way to implement this is to open a separate socket bound to each IP, and use select() or epoll() to wait for a request on all of them concurrently. Then you send the reply through the same socket that the request was received on, and it will use that socket's bound IP as the source.

(Linux has socket extensions that make this unnecessary, see Setting the source IP for a UDP socket.)

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • So for the question #3: If I don't use non-blocking socket, then I just need to wait for the socket for data, then repeat, right? Considering the performance for n UDP clients --> 1 UDP server, which one is more efficient (non-blocking + select(), or blocking socket) on the UDP server side? – Howard Shane Jun 28 '16 at 17:39
  • If you use non-blocking socket, then while you're blocked on socket1, you can't process anything received on socket2. Maybe your question is really about why you would need more than one UDP socket? – Barmar Jun 28 '16 at 19:13