我有小型服务器和客户端 Python 脚本,其中客户端发送一个字符串,服务器以相反的方式响应。当客户端输入退出字符串时,客户端退出,然后服务器退出。
我希望服务器的“接收、反向、发送”过程在后台运行,同时程序不断检查标准输入以获取退出字符串。
我试过使用threading
,但由于阻塞,许多套接字调用导致它无法正常工作。
这样您就可以了解我已经完成的工作。
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()
最佳答案
由于您希望服务器进程能够处理客户端,同时从服务器的 stdin
接收输入,您可以将整个当前服务器代码放在一个 Thread 中
,然后等待来自 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
并且您可以删除客户端中的“退出”检查。
在这段代码中,服务器在客户端断开连接后什么都不做,不过,它只会等待在 stdin
中输入“exit”。您可能希望扩展代码以使服务器能够接受新客户端,因为您不希望客户端能够关闭服务器。在这种情况下,您可以放置另一个 while
循环,从 conn = sock.accept()
到 sock.close()
。
正如@usmcs 所建议的那样,如果您没有任何其他命令要发送到服务器,那么最好使用 CTRL-C (KeyboardInterrupt
),这样您就不必不需要线程,但它仍然可以使用以下代码优雅地结束服务器(意味着不会报告由于 CTRL-C 引起的错误):
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()
关于python - 如何在不断检查输入线程的同时运行后台程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22648765/