如何在Python中通过特定按键中断recvfrom()调用?
无线程实现UDP接收与键盘中断切换方案
核心思路
在Linux环境下,利用select.select()实现IO多路复用,同时监听UDP套接字和标准输入(stdin)。这样程序可以在等待UDP消息的同时,实时检测键盘输入,无需额外线程。当检测到'+'键时,切换到发送消息模式,完成操作后可返回接收状态。
修改后的完整代码
import socket import sys import select # 解析命令行参数 if len(sys.argv) == 3: ip = sys.argv[1] port = int(sys.argv[2]) else: print("运行方式: python3 server.py <服务器IP:如192.168.1.6> <端口:如4444>") exit(1) # 创建UDP套接字并绑定 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_address = (ip, port) s.bind(server_address) client_addr = None # 存储目标客户端地址,用于后续发送消息 def recv_udp_data(): global client_addr data, client_addr = s.recvfrom(4096) print(f"收到消息: {data.decode('utf-8')}") def send_udp_data(msg): if not client_addr: print("未收到任何客户端消息,无法确定发送目标") return s.sendto(msg.encode('utf-8'), client_addr) print(f"已发送消息: {msg}") def main(): # 监听UDP套接字和标准输入 watch_fds = [s, sys.stdin] while True: # 等待IO就绪,无超时一直阻塞 readable, _, _ = select.select(watch_fds, [], []) for fd in readable: if fd == s: # UDP套接字有数据到达 recv_udp_data() elif fd == sys.stdin: # 读取键盘输入的单个字符 key = sys.stdin.read(1) if key == '+': print("\n进入发送模式:输入消息回车发送,输入'q'返回接收模式") while True: send_content = input("> ") if send_content.strip() == 'q': print("回到接收模式...") break send_udp_data(send_content) if __name__ == "__main__": main()
关键细节说明
- IO多路复用:
select.select()会阻塞直到监听的文件描述符(UDP套接字/标准输入)有可读事件,避免了单线程下只能等待一种IO的问题。 - 模式切换逻辑:通过嵌套循环实现接收/发送模式的切换,全程在单线程内完成,无需线程开销。
- 键盘输入处理:用
sys.stdin.read(1)读取单个字符,确保能及时捕捉到'+'按键;发送模式下用input()读取整行消息,符合常规输入习惯。 - 客户端地址管理:自动记录最后一个发送消息的客户端地址,后续发送消息直接复用该地址,若需支持多客户端可扩展为地址列表。
内容的提问来源于stack exchange,提问作者LazyTurtle
相关产品推荐
相关产品推荐

