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

标签 python multithreading sockets concurrency python-multithreading

我有小型服务器和客户端 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/

相关文章:

python - 当函数返回pandas数据帧时,如何在python中编写并行枚举for循环

c# - .net ExternalSigninAsync MissingMethodException 系统.Threading.tasks

c# - 等待前先释放锁,等待后重新获取

multithreading - 关于 Keras fit_generator() 中的多处理和工作人员与 spyder 中的 Windows 10 的混淆

java.net.绑定(bind)异常 : Address already in use: JVM_Bind

python - 逐字节读取套接字数据并以字符串形式返回

python - 为什么OpenCV不使用Python的CV2给这个矩形一个颜色

python - 在单个 View 方法中接受多种请求类型的更好方法?

java - Netty Nio 在 Java 中读取来自 ChannelFuture 的即将到来的消息

python - 如何在 Python zlib 模块中设置参数