Non-blocking socket in Python?

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

I'm not sure how to work exactly with .recv and .send in it. According to python docs (at least my understanding), recv 'ed or send ' data can only be partial data. This means that I have to somehow combine the data in recv and make sure that all the data is sent via send . If so, how? An example would be greatly appreciated.

+7
source share
2 answers

It doesn't really matter if your socket is in non-blocking mode or not, recv / send works almost the same way; the only difference is that a non-blocking socket generates a "Resource temporarily unavailable" error instead of waiting for data / socket.

Method

recv returns the number of bytes received, which are said to be less than or equal to the transmitted bufsize. If you want to get exactly the size of the 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 

It is important to remember that in lock mode you must do the same. (The number of bytes transferred to the application layer, for example, is limited by the size of the recv buffer in the OS.)

The send method returns the number of bytes sent, which is said to be less than or equal to the length of the transmitted string. If you want the whole message to be 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 directly use sock.sendall, but (according to the documentation) about the error, an exception is thrown and there is no way to determine how much data was sent successfully.

Sockets in Python follow the BSD API and behave similarly to c-style sockets (the difference, for example, is that they throw an exception instead of returning an error code). You should be happy with any online socket tutorial and manpages.

+8
source

Store the bytes you want to send to the buffer. (A list of byte strings would be better since you do not need to concatenate them.) Use the fcntl.fcntl function to set the socket to non-blocking mode:

 import fcntl, os fcntl.fcntl(mysocket, fcntl.F_SETFL, os.O_NONBLOCK) 

Then select.select will tell you when it will normally read and write to the socket. (Writing when it is not OK will give you an EAGAIN error in non-blocking mode.) When you write, check the return value to see how many bytes have been written. Eliminate this number of bytes from your buffer. If you use the "list of lines" approach, you only need to try writing the first line each time.

If you read an empty string, your socket closes.

0
source

All Articles