如何在不断检查输入的同时运行后台程序 - 线程?

lig*_*ght 6 python sockets concurrency multithreading python-multithreading

我有小型服务器和客户端Python脚本,客户端发送字符串,服务器响应相反.当客户端输入退出字符串时,客户端退出,然后服务器退出.

我希望服务器的"接收,反向,发送"过程在后台运行,同时程序不断检查stdin是否有退出字符串.

我尝试过使用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()
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

jus*_*alf 11

由于您希望服务器进程能够在接收来自服务器的输入的同时处理客户端stdin,因此您可以将整个当前服务器代码放入a 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
Run Code Online (Sandbox Code Playgroud)

并且您可以删除客户端中的"退出"检查.

在这段代码中,服务器在客户端断开连接后什么都不做,但是,它只是等待"退出"输入stdin.您可能希望扩展代码以使服务器能够接受新客户端,因为您不希望客户端能够关闭服务器.在这种情况下,你可以把另一个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()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。这是我预想的。 (2认同)