Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to close a blocking socket while it is waiting to receive data?

I have a service that uses a blocking socket to receive data. The problem I have is that I do not know how to properly close the socket if it is still waiting for data. Below is a short snip of how I am opening and waiting for data: I do not want to implement timeouts as according to the python documentation the socket must be blocking in order to use makefile.

I may be going about this completely wrong as I am new to programming with sockets.

EDIT:

It should be noted that the I cannot alter how the server operates.

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
reader = s.makefile("rb")
line = reader.readline()
like image 773
Richard Avatar asked Sep 27 '11 16:09

Richard


2 Answers

There is a quite simple solution. Given a socket and a reader file object like rfile = socket.makefile('rb'), in order to make rfile.readline() return immediately when the socket is closed, you need to execute the following in a separate thread:

socket.shutdown(socket.SHUT_RDWR)
socket.close()

Calling socket.shutdown() will make rfile.readline() return an empty str or bytes, depending on the version of Python (2.x or 3.x respectively).

like image 139
David Bonnet Avatar answered Nov 15 '22 06:11

David Bonnet


One solution to close this socket is to ask the server to close it.

If server close the client socket, the client will receive a "Connection reset by peer" error, and it may break the blocking receive.

Another solution would be to not use readline() and put a timeout on your socket (indefinite wait could wait.... indefinitely)

like image 39
Cédric Julien Avatar answered Nov 15 '22 05:11

Cédric Julien