Host
) import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8080))
s.listen(10)
while True:
conn, addr = s.accept()
path = conn.recv(512).decode('utf8').rstrip("\r\n")
file = open('/www' + str(path), 'r')
data = file.read().encode('utf8')
conn.sendall(data)
file.close()
conn.close()
проблема вышеописанного сервера в том, что он не способен обрабатывать больше одного соединения одновременно.
Проблема особенна актуальна в случае медленной обработки запроса (медленный клиент, или медленная бизнес логика)
Блокирующий ввод-вывод
Неблокирующий ввод-вывод
после того как приложение отправило сообщение на ввод\вывод ядро возвращает сигнал EAGAIN/E_WOULDBLOCK
. Это значит что операция в процессе выполнения и нужно позже спросить у ядра (так же методом recv
), выполнилась ли она.
такой подход называется мультиплексированием
readsocks, writesocks = [...], [...] # сокеты
while True:
# readables - список сокетов, готовых для чтения (там уже есть данные и не нужно ждать их от клиента)
# writables - список сокетов, готовых для записи (есть буфер достаточного размера)
readables, writeables, exceptions = select(readsocks, writesocks, [])
for sockobj in readables:
data = sockobj.recv(512)
if not data:
sockobj.close()
readsocks.remove(sockobj)
else:
print('\tgot', data, 'on', id(sockobj))