不同的进程可以同时绑定同一个端口吗

不同的进程可以同时绑定同一个端口吗?
当听到这个问题的时候,你的第一反应是不是肯定不行啊(如果你在工作中遇到过address already in use的情况)。大家都知道tcp通过四元组来确定一个唯一的连接,所以说理论上说不同的进程应该不能使用同一个端口。

其实在Linux3.9内核中引入了一个socket选项SO_REUSEPORT,如果在创建socket的时候添加了这个选项,就允许多个进程绑定到同一个端口。

多个进程监听同一个端口,那服务端是怎么处理客户端连接呢?
内核将以round-robin的方式在进程之间分配传入的连接,这意味着每个进程将依次接收相等数量的连接。

可以使用如下的代码,分别在不同的终端运行下面的代码对上面提出的问题进行验证。
如果在不同的终端都可以运行这段代码说明不同的进程可以占用同一个端口;然后可以在客户端curl服务端,观察日志输出就知道连接了哪个进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import socket

# create a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# set the SO_REUSEPORT option
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

# bind the socket to the port
sock.bind(('localhost', 12345))

# listen for incoming connections
sock.listen()

while True:
# accept incoming connections
conn, addr = sock.accept()
print(f"Connection from {addr}")

# receive data from the client
data = conn.recv(1024)
print(f"Received data: {data.decode()}")

# send a response back to the client
response = "Hello, client!"
conn.send(response.encode())

# close the connection
conn.close()