Я изучаю сокеты со следующим python кодом для сервера:
import selectors
import socket
import types
host = "127.0.0.1"
port = 65432
def accept_wrapper(sock):
conn, addr = sock.accept()
print('accepted conneciton from', addr)
conn.setblocking(False)
data = types.SimpleNamespace(addr=addr, inb=b'', outb=b'')
events = selectors.EVENT_READ | selectors.EVENT_WRITE
sel.register(conn, events, data=data)
def service_connection(key, mask):
sock = key.fileobj
data = key.data
if mask & selectors.EVENT_READ:
recv_data = sock.recv(1024)
if recv_data:
data.outb += recv_data
else:
print('closing connection to', data.addr)
sel.unregister(sock)
sock.close()
if mask & selectors.EVENT_WRITE:
if data.outb:
print('echoing', repr(data.outb), 'to', data.addr)
sent = sock.send(data.outb)
data.outb = data.outb[sent:]
sel = selectors.DefaultSelector()
lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
lsock.bind((host, port))
lsock.listen()
print('listening on', (host, port))
lsock.setblocking(False)
sel.register(lsock, selectors.EVENT_READ, data=None)
while True:
events = sel.select(timeout=None)
for key, mask in events:
if key.data is None:
# From the listening socket
accept_wrapper(key.fileobj)
else:
# Client Socket
service_connection(key, mask)
и следующим для клиента
import socket
import selectors
import types
host = "127.0.0.1"
port = 65432
numm_conns = 2
messages = [b'Message 1 from client', b'Message 2 from client']
def start_connections(host, port, num_conns):
server_addr = (host, port)
for i in range(0, num_conns):
connid = i + 1
print('starting connection', connid, 'to', server_addr)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)
sock.connect_ex(server_addr)
events = selectors.EVENT_READ | selectors.EVENT_WRITE
data = types.SimpleNamespace(
connid = connid,
msg_total=sum(len(m) for m in messages),
recv_total = 0,
messages=list(messages),
outb=b''
)
sel.register(sock, events, data=data)
def service_connection(key, mask):
sock = key.fileobj
data = key.data
if mask & selectors.EVENT_READ:
recv_data = sock.recv(1024)
if recv_data:
print('received', repr(recv_data), 'from connection', data.connid)
data.recv_total += len(recv_data)
if not recv_data or data.recv_total == data.msg_total:
print('closing connection', data.connid)
sel.unregister(sock)
sock.close()
if mask & selectors.EVENT_WRITE:
if not data.outb and data.messages:
data.outb = data.messages.pop(0)
if data.outb:
print('sending', repr(data.outb), 'to connection', data.connid)
sent = sock.send(data.outb)
data.outb = data.outb[sent:]
sel = selectors.DefaultSelector()
start_connections(host, port, numm_conns)
while True:
events = sel.select(timeout=None)
print()
print(events)
print()
for key, mask in events:
service_connection(key, mask)
На клиенте первое событие, которое срабатывает в случае, если l oop для обоих сокетов равно 2, что означает, что сокеты готовы к записи. Мой вопрос: почему не было события 3? Разве они не должны быть доступны для чтения? Или это событие срабатывает только тогда, когда что-то было недавно записано в сокет?