Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-blocking socket in Python?

Tags:

python

sockets

Is it me, or can I not find a good tutorial on non-blocking sockets in python?

I'm not sure how to exactly work the .recv and the .send in it. According to the python docs, (my understanding of it, at least) the recv'ed or send'ed data might be only partial data. So does that mean I have to somehow concatenate the data while recv and make sure all data sends through in send. If so, how? An example would be much appreciated.

like image 564
Pwnna Avatar asked Jul 16 '11 07:07

Pwnna


1 Answers

It doesn't really matter if your socket is in non-blocking mode or not, recv/send work pretty much the same; the only difference is that non-blocking socket throws 'Resource temporarily unavailable' error instead of waiting for data/socket.

recv method returns numbers of bytes received, which is told to be less or equal to the passed bufsize. If you want to receive exactly size bytes, you should do something similar to the following code:

def recvall(sock, size):
  data = ''
  while len(data) < size:
    d = sock.recv(size - len(data))
    if not d:
      # Connection closed by remote host, do what best for you
      return None
    data += d
  return data

This is important to remember, that in blocking mode you have to do exactly the same. (The number of bytes passed to application layer is for example limited by recv buffer size in the OS.)

send method returns number of bytes sent, which is told to be less or equal to the length of passed string. If you want to ensure the whole message was sent, you should do something similar to the following code:

def sendall(sock, data):
  while data:
    sent = sock.send(data)
    data = data[sent:]

You can use sock.sendall directly, but (according to the documentation) on error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent.

The sockets in Python follow the BSD socket API and behave in the similar way to c-style sockets (the difference is, for example, they throw exception instead of returning error code). You should be happy with any socket tutorial on the web and manpages.

like image 190
tomasz Avatar answered Sep 22 '22 10:09

tomasz