Я пишу базовое клиент-серверное приложение. Вот оно.
Сервер:
import socket
from multiprocessing import Process
def process_request(conn, addr):
print('connected client:', addr)
with conn:
while True:
data = conn.recv(1024)
if not data:
break
print(data.decode('utf8'))
if __name__ == '__main__':
with socket.socket() as sock:
sock.bind(('', 10001))
sock.listen()
while True:
conn, addr = sock.accept()
p = Process(target = process_request, args = (conn, addr))
print('starting new process')
p.start()
p.join()
Клиент:
import socket
from time import sleep
from multiprocessing import Pool
def create_socket_and_send_data(number):
print(f'start sending data for {number}')
with socket.create_connection(('127.0.0.1', 10001)) as sock:
try:
sock.sendall(f'sending data from {number} socket (1)\n'.encode('utf8'))
sleep(2)
sock.sendall(f'sending data from {number} socket (2)\n'.encode('utf8'))
except socket.error as ex:
print('send data error', ex)
print(f'all data for {number} is sended')
if __name__ == '__main__':
with Pool(processes=3) as pool:
pool.map(create_socket_and_send_data, range(5))
Выход клиента:
$ python 59_several_connection_client.py
start sending data for 0
start sending data for 1
start sending data for 2
all data for 0 is sended
all data for 1 is sended
all data for 2 is sended
start sending data for 3
start sending data for 4
all data for 3 is sended
all data for 4 is sended
Выход сервера:
starting new process
connected client: ('127.0.0.1', 63476)
sending data from 0 socket (1)
sending data from 0 socket (2)
starting new process
connected client: ('127.0.0.1', 63477)
sending data from 1 socket (1)
sending data from 1 socket (2)
starting new process
connected client: ('127.0.0.1', 63478)
sending data from 2 socket (1)
sending data from 2 socket (2)
starting new process
connected client: ('127.0.0.1', 63479)
sending data from 3 socket (1)
sending data from 3 socket (2)
starting new process
connected client: ('127.0.0.1', 63480)
sending data from 4 socket (1)
sending data from 4 socket (2)
У меня есть несколько вопросов. Прежде всего, я не понимаю, почему последовательность вывода такая. Я думал , что это будет похоже на
data from socket 0 (1)
data from socket 1 (1)
data from socket 2 (1)
# now the pull is full, processes are sleeping
data from socket 0 (2)
data from socket 3 (1)
data from socket 1 (2)
data from socket 4 (1)
data from socket 2 (2)
# pay attention that pool had contained 3 processes,
# it finished them one by one, so new places in the pool
# were occupied by fresh processes that started to execute
#
# now old 3 processes have been finished
# and pull contains 2 new processes, they are sleeping
data from socket 4 (2)
data from socket 3 (2)
# all ok, 2 processes are done
Но неожиданно вывод получается последовательным, как будто код выполняется в одном потоке. Зачем? Может ли кто-нибудь объяснить, где разрыв в моих мыслях?
И второй крошечный вопрос: почему выходные данные иногда содержат пустые строки?