How to run a background procedure while constantly checking for input - threading?
concurrency, multithreading, python, python-multithreading, sockets
Solution
Since you want the server process to be able to handle the client while in the same time receiving input from the server's `stdin`, you can just put the whole current server code in a `Thread`, then wait input from `stdin`.
import socket
from time import sleep
import threading
def process():
sock = socket.socket()
sock.bind(("127.0.0.1",12346))
sock.listen(3)
print "Waiting on connection"
conn = sock.accept()
print "Client connected"
while True:
m = conn[0].recv(4096)
conn[0].send(m[::-1])
sock.shutdown(socket.SHUT_RDWR)
sock.close()
thread = threading.Thread(target=process)
thread.daemon = True
thread.start()
while True:
exit_signal = raw_input('Type "exit" anytime to stop server\n')
if exit_signal == 'exit':
break
and you can remove the "exit" checking in client.
In this code, the server will be doing nothing after the client disconnect, though, it will just wait for "exit" to be typed in the `stdin`. You might want to extend the code to make the server able to accept new clients, since you don't want the client to have the ability to close the server. In that case, you can put another `while` loop from `conn = sock.accept()` to `sock.close()`.
And as @usmcs suggested, if you don't have any other command to be sent to the server, it will be better if you use CTRL-C (`KeyboardInterrupt`) instead, so you don't need the thread, while it can still end the server gracefully (meaning no error due to the CTRL-C is reported) with this code:
import socket
from time import sleep
import threading
sock = socket.socket()
sock.bind(("127.0.0.1",12346))
sock.listen(3)
print "Waiting on connection"
conn = sock.accept()
print "Client connected"
while True:
try:
m = conn[0].recv(4096)
conn[0].send(m[::-1])
except KeyboardInterrupt:
break
sock.close()
Problem
I have small server and client Python scripts where the client sends a string and the server responds with the reverse. When the client enters a quit string, the client exits and then the server exits. I want the server's "receive, reverse, send" procedure running in the background while the program is constantly checking stdin for a quit string. I've tried using `threading` but because of the blocking that many socket calls cause it wouldn't work properly. Just so you can get an idea of what I've already done. server.py: ``` import socket from time import sleep sock = socket.socket() sock.bind(("127.0.0.1",12346)) sock.listen(3) print "Waiting on connection" conn = sock.accept() print "Client connected" while True: m = conn[0].recv(4096) if m == "exit": sleep(1) break else: conn[0].send(m[::-1]) sock.shutdown(socket.SHUT_RDWR) sock.close() ``` client.py: ``` import socket sock = socket.socket() sock.connect(("127.0.0.1",12346)) while True: s = raw_input("message: ") sock.send(s) if s == "exit": print "Quitting" break print sock.recv(4096) sock.shutdown(socket.SHUT_RDWR) sock.close() ```