If I have this code relating to an unblocking socket called sock
recv_data = sock.recv(1024)
if recv_data:
data.outb += recv_data
else:
print('closing connection to', data.addr)
sel.unregister(sock)
sock.close()
What exactly happens? How is the statement recv_data = sock.recv(1024)
differ from blocking and nonblocking? If the program doesn't wait for that statement to complete, how does recv_data
ever have value?
Edit: Full server code:
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)
If sock
is non-blocking, it will raise BlockingIOError
if it would block otherwise. Is there a try
/ except
not shown around the code? Another option is select.select
is used to make sure there is data read to receive before calling recv
.
Example assuming appropriate server:
>>> from socket import *
>>> s=socket()
>>> s.connect(('localhost',5000))
>>> s.setblocking(0)
>>> s.recv(1024)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately
Edit:
With the additional code, recv
is only called when sel.select
reports an EVENT_READ
(data ready to read) so recv
should not block. It will either return data or an empty string. The latter indicates the socket was closed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.