如何让Python Socket程序每秒打印Hi直到执行toggle命令?
问题解决:实现每秒打印Hi直到收到toggle命令停止
你的代码问题出在s.accept()是阻塞式调用——程序执行到这一行就会暂停,等待客户端连接,所以只会打印一次Hi就卡住,无法继续循环打印。要实现每秒打印Hi直到收到toggle信号,需要把打印逻辑和Socket监听逻辑并行处理,这里用多线程来实现:
修改后的完整代码
import click import time import socket import threading from threading import Lock # 全局变量与线程锁,确保多线程下变量修改安全 j = 0 lock = Lock() @click.group(chain=True) def cli(): pass def socket_server(): """单独线程运行Socket服务器,监听toggle命令""" global j with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((socket.gethostname(), 1234)) s.listen(5) # 等待连接,收到数据后修改j的值 clientsocket, address = s.accept() with clientsocket: print(f"Connection from {address} has been established!") msg = clientsocket.recv(1024) decodedmsg = msg.decode().strip() print(decodedmsg) with lock: j += int(decodedmsg) print(f"j updated to: {j}") @cli.command() def main(): global j # 启动Socket服务器线程 server_thread = threading.Thread(target=socket_server, daemon=True) server_thread.start() # 主线程每秒打印Hi,直到j不为0 while j == 0: print("Hi") time.sleep(1) print("Stopped printing Hi.") @cli.command() def toggle(): clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: clientSocket.connect((socket.gethostname(), 1234)) data = "1" clientSocket.send(data.encode()) print("Toggle signal sent.") except ConnectionRefusedError: print("Error: Main server is not running.") finally: clientSocket.close() if __name__ == "__main__": cli()
关键改动说明
- 新增
threading模块,把Socket服务器逻辑放到单独线程socket_server中运行,避免阻塞主线程的打印循环。 - 添加线程锁
Lock(),确保多线程修改全局变量j时的安全性(防止竞态条件)。 - 修正原代码中的拼写错误
estanblishded为established。 - 给
toggle命令添加异常处理,提示用户如果主服务器未运行的错误。 - 主线程专注于每秒打印
Hi,直到j变为非0值后退出循环。
运行方式
- 先在一个终端启动主程序:
此时会每秒打印一次python3 pathto/program.py mainHi。 - 再打开另一个终端发送toggle命令:
主程序会收到信号,停止打印python3 pathto/program.py toggleHi并退出。
内容的提问来源于stack exchange,提问作者IloveMath
相关产品推荐
相关产品推荐

