I've written a Pi Hardware Interface Server (phis) that uses http protocol to control the hardware connected to my Raspberry Pi (relays, analog measurements, etc). It processes simple requests and responds with plain text. It has been working flawlessly for years and I have written extensive browser-based interfaces to the system. Here's the basic structure:
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
read_list = [listen_socket]
while True:
readable, writeable, errored = select.select(read_list,[], [], 2)
if len(readable) == 0: # select timed out
continue
client_connection, client_address = listen_socket.accept()
try:
request = client_connection.recv(1024)
except Exception:
print "Exception trying to recv, %s" % time.strftime(date_format)
sys.exc_clear()
client_connection.close()
continue
words = request.split()
http_response = """\
HTTP/1.1 200 OK
"""
try:
client_connection.sendall(http_response)
except Exception:
print "Exception trying to send 1, %s" % time.strftime(date_format)
sys.exc_clear()
client_connection.close()
continue
http_response = """\
Content-Type: text/plain; charset=utf-8
"""
# perform some action and add text to the http_response (like current CPU temperature, etc)
try:
client_connection.sendall(http_response)
except Exception:
# log the error, then...
sys.exc_clear()
client_connection.close()
continue
client_connection.close()
if words[1] == '/exit':
sys.exit(0)
The problem occurs when the command is to start mjpg_streamer. The stream starts just fine, the response is sent and I can make more connections and issue new commands, but the client_connection.close() never actually closes the connection and the browser just sits there waiting for more stuff that never comes. The phis is still accepting new connections and servicing those, but if I exit the server with the request "http://pi:4000/exit", it does so cleanly, but it wont start again (socket in use) unless I first issue the request to stop mjpg_streams (which also works just fine).
mjpg_streamer already starts in (what seems to be) a daemonized background mode, but in my attempts to get this working, I have issued the command to start it in every python "start your background child and leave it running" method I could find (os.system(), subprocess.Popen(), os.fork() and os.fork() twice with os.setsid() in between). Nothing worked.
If it matters, I'm actually calling a perl script from the phis that starts mjpg_steamer with command line arguments based on arguments passed to the perl script.
I have googled much on this and found others with connections that would not close, but not with connections that close perfectly unless some background socket-based app is spawned while the connection is active. Anyone have any idea what's wrong?