45

I've been reading this tutorial to learn about socket programming. It seems that the listen() and accept() system calls both do the same thing, which is block and wait for a client to connect to the socket that was created with the socket() system call. Why do you need two separate steps for this? Why not just use one system call?

By the way, I have googled this question and found similar questions, but none of the answers were satisfactory. For example, one of them said that accept() creates the socket, which makes no sense, since I know that the socket is created by socket().

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Zen Hacker
  • 733
  • 2
  • 6
  • 13

4 Answers4

55

The listen() function basically sets a flag in the internal socket structure marking the socket as a passive listening socket, one that you can call accept on. It opens the bound port so the socket can then start receiving connections from clients.

The accept() function asks a listening socket to accept the next incoming connection and return a socket descriptor for that connection. So, in a sense, accept() does create a socket, just not the one you use to listen() for incoming connections on.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
34

It is all part of the historic setup. listen prepares socket for the next accept call. Listen also allows one to setup the backlog - the number of connections which will be accepted by the system, and than put to wait until your program can really accept them. Everything which comes after the backlog is full well be rejected by the system right away. listen never blocks, while accept will block (unless the socket is in non-blocking mode) until the next connection comes along. Obviously, this does not have to be two separate functions - it is conceivable that accept() function could do everything listen does.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
11

The above two answers clearly state the difference between accept and listen. To answer your other question - why we need two separate functions?

One use case is, for e.g. if you only want to test if a port is still available/and accessible, you can do so by just listening to the port and then closing it without accepting any connections.

For e.g. https://github.com/coolaj86/golang-test-port uses the listen call for testing a port's availability.

J Aamish
  • 522
  • 7
  • 12
1

listen() uses a backlog parameter which specifies the maximum number of queued connections and should be at least 0. It's value increases as the server receives a lot of connection requests simultaneously.

accept() waits for incoming connections. When a client connects, it returns a new socket object representing the connection.

Another imperative thing to note is that accept() creates a new socket object which will be used to communicate with the client. It is different from the listening socket that server uses to accept new connections.

Maximum number of sockets allowed per each connection between an application and the TCP/IP sockets interface is 65535.