Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone help me to clear my understanding of TCP/IP System calls?

  1. listen(5): Here, Does it mean that server can be connected to only 5 clients?
  2. select(): As per wiki select system call is used when we continuously wants to monitor the port for input/output,then if we don't use select() then also we can monitor that particular port right?
  3. While accepting the connection we have to use select() system call, why can't we use simple array to save the newsfd?

for ex: (using Python)

SocketFd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SocketFD.bind((ip, port))
SocketFd.listen(5)
i = 0
NewSFD = []
while True:
     NewSFD[i] = SocketFd.accept()
     i += 1
     if i == 5:
         break
like image 856
Chirag Gangdev Avatar asked Feb 10 '23 20:02

Chirag Gangdev


1 Answers

  1. The argument to listen is the backlog of connections - that is, the number of connections that can be queued by the kernel that you haven't accepted (because your program can't respond instantly). Set it to 1 if you only have one client, otherwise pass SOMAXCONN.

  2. There are three ways to implement a server: servers that only have one client at a time (and are thus boring, though you do still have to worry about which direction you're sending traffic), servers that allocate one thread per client (which can be costly and requires synchronization) and use blocking calls, and servers that use a single thread and use nonblocking calls (though it is sometimes possible to do load-balancing between multiple threads with this technique). I am only focusing on the third kind here.

In order to use nonblocking sockets, you must set the O_NONBLOCK flag (which allows read and write to return EAGAIN (in errno)), then pass all of the sockets to one of the multiplexing syscalls. Originally there was select, but poll is a much better alternative and is also standard. Nonstandard alternatives include epoll on Linux and kqueue on *BSD (including Mac OS X).

Your chosen multiplexing syscall will let your program sleep until there is activity on one of the sockets you are interested in. Otherwise, you would have to burn 100% CPU trying every file descriptor in turn even though most of them are going to be EAGAIN at any given moment, but wasting CPU is an unforgivable sin. In my (admittedly anecdotal) experience, a server will usually use about 10% CPU with a typical number of clients (the limiting factor is usually the bandwidth of the client). But it is absolutely essential that your server uses 0% CPU when no client is connected (unless it also has tasks that must be executed on a timer even when no client is watching).

Note that the multiplexing syscalls take a timeout, which should be set to how long until the next timer is scheduled (timers are usually stored in a heap and the earliest timer is the root). If you don't have any timers scheduled, there is a special value that indicates "forever".

  1. I'm not sure what you're asking, you don't have to use select in order to accept. However, if you pass the listening socket to select (this is required to have more than one client in the nonblocking model), it will appear as readable when accept might return a new client (though spurious notifications are always possible).
like image 97
o11c Avatar answered Feb 12 '23 09:02

o11c