У меня очень простой tcp сервер на python, код которого приведен ниже:
#!/usr/bin/env python
import socket
sock = socket.socket()
sock.bind(('',3912))
sock.listen(100)
num_cons = 10
cons = []
for i in range(num_cons):
con, addr = sock.accept()
cons.append(con)
while True:
for con in cons:
msg = "a"* 1000
num_sent = con.send(msg.encode())
print("sent: {} bytes of msg:{}".format(str(num_sent), msg))
Соответствующий код клиента
#!/usr/bin/env python
import socket
sock = socket.socket()
sock.connect(('',3912)) # in reality here I use the IP of the host where
# I run the server since I launch the clients on a different host
while True:
data = sock.recv(1000)
print("received data: {} ".format(str(data)))
Теперь, если я запускаю сервер с
./server.py
и 10 клиентов параллельно с другого хоста:
for i in `seq 1 10`; do ./client.py 2>/dev/null 1>/dev/null & done
И я отправляю kill -SIGSTOP %1
первому клиенту, я ожидаю, что сервер успешно продолжит попытки отправки данных, потому что он не может знать, что клиент был остановлен. Вместо этого сервер блокируется, когда он пытается отправить данные клиенту 1. Я могу понять поведение, если клиенты находились на том же хосте, что и сервер: мы пытались записать данные, но буферы ядра заполнены, поэтому мы блокируем сервер, но клиент никогда не читает, поэтому буфер никогда не освобождается. Однако, если клиенты находятся на другом компьютере, буферы ядра хоста сервера должны быть заполнены только временно, а затем ядро должно отправить данные по сетевой карте и освободить их. Так почему мой сервер блокирует вызов send
? Я не проверял, наблюдается ли такое же поведение при использовании другого языка (например, C)