You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现简易TELNET客户端问题:无数据时循环停滞无法发送命令

解决Python极简TELNET客户端收发数据的循环停滞问题

嘿,我之前开发Telnet工具时也踩过这个坑!你的问题根源很明确:recv()是阻塞式方法——只要服务器没有数据推送过来,这个调用就会一直挂起,完全没法处理用户输入命令的操作。

问题代码分析

你当前的循环逻辑是先等着收数据,再处理输入,顺序完全反了,而且还缺少连接断开后的退出逻辑:

# Infinite cycle that allows user to get and send data from/to the host
while True:
    incoming_data = my_socket.recv(4096)
    if not incoming_data:
        print('Problem occurred - Connection closed')
        my_socket.close()
        # 这里缺失break,会导致无限循环报错
    # 没有处理用户输入的逻辑,且recv阻塞后根本到不了输入步骤

推荐解决方案:用select模块监听多输入源

select模块能让你同时监听套接字和标准输入(用户键盘输入),哪个有数据就处理哪个,完美解决阻塞问题。下面是修改后的完整示例:

import socket
import select
import sys

def main():
    # 假设你已经完成socket连接步骤,示例如下:
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    my_socket.connect(("your_host", 23))  # Telnet默认端口为23

    print("Connected to Telnet server! Type commands below:")
    
    while True:
        # 用select监听socket和标准输入两个可读源
        readable, _, _ = select.select([my_socket, sys.stdin], [], [])
        
        for source in readable:
            if source == my_socket:
                # 处理服务器发来的数据
                incoming_data = my_socket.recv(4096)
                if not incoming_data:
                    print('\nConnection closed by server')
                    my_socket.close()
                    return
                # 打印收到的内容,忽略Telnet可能的特殊控制字符
                print(incoming_data.decode('utf-8', errors='ignore'), end='')
            else:
                # 处理用户输入的命令
                command = sys.stdin.readline()
                if not command:
                    continue
                # 发送命令到服务器,Telnet通常需要换行符触发执行
                my_socket.send(command.encode('utf-8'))

if __name__ == "__main__":
    main()

关键细节说明

  • select.select()会返回当前有数据可读的对象列表,这样我们就能同时响应服务器消息和用户输入,不会再被单一的recv()阻塞。
  • 编码处理:Telnet数据可能包含非UTF-8的控制字符,用errors='ignore'可以避免解码报错,保证程序稳定运行。
  • 用户输入的命令要带上换行符,大部分Telnet服务器需要这个标记来识别命令结束。

其他可选方案

如果觉得select不够直观,也可以用多线程:一个线程专门处理接收服务器数据,另一个线程处理用户输入和发送命令。不过多线程需要注意线程安全,对于简单的Telnet客户端来说,select是更轻量、更易维护的选择。

内容的提问来源于stack exchange,提问作者matteo-g

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:26:25