When I read the How TCP backlog works in Linux, I see the following question in the comment without an explanation. Here is a simple test socket server.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import socket
HOST = ''
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while 1:
pass
Mac os
First, Run server on my macOS and use nc
to connect to the server, the behavior is:
- accept the first
nc
connection - the second
nc
connection is hanging and resending the SYN packet.
Which is just as expected.
Because:
Historically, BSD derived TCP implementations use the first approach. That choice implies that when the maximum backlog is reached, the system will no longer send back SYN/ACK packets in response to SYN packets. Usually the TCP implementation will simply drop the SYN packet (instead of responding with a RST packet) so that the client will retry.
Centos 7(Linux)
Then run it on a Linux machine to do the same thing, the behavior is:
- accept the first connection.
- accept the second connection!
- the third connection hangs and resending the ACK packet, the server at the same time, resending the SYN/ACK.
The second connection is established somehow.
The question is, why the server can accept 2 connections on Linux and only one on macOS.
The relevant question
Steffen Ullrich mark it as same with another question: listen() ignores the backlog argument?.
The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket's listen queue.
It seems true. But at the same time, python doc says:
socket.listen(backlog) Listen for connections made to the socket. The backlog argument specifies the maximum number of queued connections and should be at least 0; the maximum value is system-dependent (usually 5), the minimum value is forced to 0.
Then maybe the python implementation just use backlog as a hint? The backlog is not the number of the connections the server would hold, but some func(backlog)
is the number behind the back. Do anyone can have a certain explain? And why the maximum value is usually 5?
PS:
when set backlog=2, the fourth connections will be hang. when set backlog=5, the sixth connections will be hang.