python 创建 Telnet 客户端

目录

前言

1. Telnet 客户端框架

2. Telnet 代码分解

2.1 基于 TK 创建会话窗口

2.1.1 创建 Text 文本控件

2.1.2 创建 Frame 容器

2.1.2.1 基于 Frame 容器创建主机地址输入框

2.1.2.1.1 主机地址输入框绑定焦点事件

2.1.2.2 创建 Telnet 连接按钮控件

2.1.2.3 创建 Telnet 断开按钮控件

2.1.2.4 基于 Frame 容器创建发送命令输入框

2.1.2.4.1 发送命令输入框绑定焦点事件

2.1.2.5 创建执行命令按钮控件

2.2 Telnet 连接与断开服务器过程

2.2.1 Telnet 连接服务器

2.2.2 Telnet 断开服务器 

2.3 Telnet 会话交互过程

2.3.1 Telnet 客户端向服务器发送命令

2.3.2 Telnet 客户端接收服务器返回的数据 

3. Telnet 客户端代码总览 

4. Telnet 客户端效果展示 

5. 总结


前言

最近由于某些特殊项目的需要,匆忙通过 python 实现了一个简易版的 Telnet 客户端。这个客户端目前来说是有缺陷的(比如,不能 vi 读写文件内容,不能执行阻塞型命令 ping 等),但是感觉比较好玩,所以想与大家分享一下。

1. Telnet 客户端框架

2. Telnet 代码分解

接下来,我们就基于 Telnet客户端框架 来逐步拆分讲解代码构成。

2.1 基于 TK 创建会话窗口

# 创建窗口并设置标题
window = tk.Tk()
window.title("Telnet客户端")# 设置tk.Tk窗口的背景颜色为浅蓝色
window.config(bg="sky blue")

2.1.1 创建 Text 文本控件

# 创建一个Text文本控件
console_text = tk.Text(window, width=200, height=70, bg="black", fg="white")
console_text.pack(pady=5)# 定义一个字体样式
console_text.tag_configure("bold_tag", font=("Arial", 11))

2.1.2 创建 Frame 容器

# 创建一个Frame用于放置输入框和按钮,并设置Frame在下方空开5个空格
frame = tk.Frame(window, bg="sky blue")
frame.pack(pady=5)

2.1.2.1 基于 Frame 容器创建主机地址输入框

# 创建一个输入框控件,并放置在Frame中,同时设置右侧空开3个空格
host_addr_entry = tk.Entry(frame, width=50, font=("Arial", 12, "bold"))
host_addr_entry.insert(0, "请输入主机地址...")
host_addr_entry.config(fg="gray")
host_addr_entry.pack(side=tk.LEFT, padx=3)
2.1.2.1.1 主机地址输入框绑定焦点事件
# 绑定获取焦点和失去焦点事件,显示和隐藏提示语
host_addr_entry.bind("<FocusIn>", on_host_entry_focus_in)
host_addr_entry.bind("<FocusOut>", on_host_entry_focus_out)# 获取焦点事件
def on_host_entry_focus_in(event):if host_addr_entry.get() == "请输入主机地址...":host_addr_entry.delete(0, tk.END)host_addr_entry.config(fg="black")# 失去焦点事件
def on_host_entry_focus_out(event):if host_addr_entry.get() == "":host_addr_entry.insert(0, "请输入主机地址...")host_addr_entry.config(fg="gray")

2.1.2.2 创建 Telnet 连接按钮控件

# 创建一个按钮控件,并放置在Frame中
connect_button = tk.Button(frame, text="连接 Telnet", font=("Arial", 12, "bold"), fg="white", bg="#46C0FB", command=connect_telnet)
connect_button.pack(side=tk.LEFT, padx=3)

2.1.2.3 创建 Telnet 断开按钮控件

# 创建断开按钮控件,并放置在Frame中,右侧空开3个空格
disconnect_button = tk.Button(frame, text="断开 Telnet", font=("Arial", 12, "bold"), fg="white", bg="#46C0FB", command=disconnect_telnet, state=tk.DISABLED)
disconnect_button.pack(side=tk.LEFT, padx=3)

2.1.2.4 基于 Frame 容器创建发送命令输入框

# 创建一个输入框控件,并放置在Frame中,同时设置右侧空开3个空格
command_entry = tk.Entry(frame, width=50, font=("Arial", 12, "bold"))
command_entry.insert(0, "请发送指令...")
command_entry.config(fg="gray")
command_entry.pack(side=tk.LEFT, padx=12)
2.1.2.4.1 发送命令输入框绑定焦点事件
# 绑定获取焦点和失去焦点事件,显示和隐藏提示语
command_entry.bind("<FocusIn>", on_entry_focus_in)
command_entry.bind("<FocusOut>", on_entry_focus_out)# 获取焦点事件
def on_entry_focus_in(event):if command_entry.get() == "请发送指令...":command_entry.delete(0, tk.END)command_entry.config(fg="black")# 失去焦点事件
def on_entry_focus_out(event):if command_entry.get() == "":command_entry.insert(0, "请发送指令...")command_entry.config(fg="gray")

2.1.2.5 创建执行命令按钮控件

# 创建执行按钮控件,并放置在Frame中,右侧空开3个空格
execute_button = tk.Button(frame, text="执行命令", font=("Arial", 12, "bold"), fg="white", bg="#46C0FB", command=execute_command, state=tk.DISABLED)
execute_button.pack(side=tk.LEFT)

2.2 Telnet 连接与断开服务器过程

2.2.1 Telnet 连接服务器

def connect_telnet():host = host_addr_entry.get() # 获取输入框内的主机地址port = 23            # 默认telnet端口username = 'root'    # 登录用户名password = '123456'  # 登录密码try:# 连接Telnet服务器telnet_client = telnetlib.Telnet(host, port, timeout=5)console_text.insert(tk.END, "成功连接到Telnet服务器。\n", "bold_tag")connect_button.config(state=tk.DISABLED)disconnect_button.config(state=tk.NORMAL)execute_button.config(state=tk.NORMAL)# 输入登录用户名telnet_client.read_until(b'login:')telnet_client.write(username.encode('ascii') + b"\n")# 输入登录密码telnet_client.read_until(b'Password:')telnet_client.write(password.encode('ascii') + b"\n")print('成功登录到设备:' + host)# 启动后台信息接收线程receive_thread = threading.Thread(target=receive_background_info)receive_thread.start()except Exception as e:console_text.insert(tk.END, f"连接失败: {e}\n", "bold_tag")

2.2.2 Telnet 断开服务器 

def disconnect_telnet():if telnet_client:telnet_client.close()console_text.insert(tk.END, "已断开Telnet连接。\n", "bold_tag")connect_button.config(state=tk.NORMAL)disconnect_button.config(state=tk.DISABLED)execute_button.config(state=tk.DISABLED)

2.3 Telnet 会话交互过程

2.3.1 Telnet 客户端向服务器发送命令

def execute_command():command = command_entry.get() + "\n"telnet_client.write(command.encode('ascii'))command_entry.delete(0, tk.END)

2.3.2 Telnet 客户端接收服务器返回的数据 

def receive_background_info():while True:try:output_data = telnet_client.read_very_eager().decode('utf-8')if output_data:clean_color_data = remove_color_codes(output_data.strip())console_text.insert(tk.END, clean_color_data, "bold_tag")time.sleep(0.5)except EOFError:breakexcept Exception as e:console_text.insert(tk.END, f"错误: {e}\n", "bold_tag")breakdef remove_color_codes(data):# 使用正则表达式匹配ANSI转义码,并替换为空字符串ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')return ansi_escape.sub('', data)

3. Telnet 客户端代码总览 

import tkinter as tk
import telnetlib
import threading
import time
import reclass TeneltTool:def __init__(self):self.window = tk.Tk()self.window.title("Telnet客户端")# 设置tk.Tk窗口的背景颜色为浅蓝色self.window.config(bg="sky blue")# 创建一个200x70的Text文本控件,并且设置背景为黑色self.console_text = tk.Text(self.window, width=200, height=70, bg="black", fg="white")self.console_text.pack(pady=5)# 定义一个字体样式self.console_text.tag_configure("bold_tag", font=("Arial", 11))# 创建一个Frame用于放置输入框和按钮,并设置Frame在下方空开5个空格frame = tk.Frame(self.window, bg="sky blue")frame.pack(pady=5)# 创建一个输入框控件,并放置在Frame中,同时设置右侧空开3个空格self.host_addr_entry = tk.Entry(frame, width=50, font=("Arial", 12, "bold"))self.host_addr_entry.insert(0, "请输入主机地址...")self.host_addr_entry.config(fg="gray")self.host_addr_entry.pack(side=tk.LEFT, padx=3)# 创建一个按钮控件,并放置在Frame中self.connect_button = tk.Button(frame, text="连接 Telnet", font=("Arial", 12, "bold"), fg="white", bg="#46C0FB",command=self.connect_telnet)self.connect_button.pack(side=tk.LEFT, padx=3)# 创建断开按钮控件,并放置在Frame中,右侧空开3个空格self.disconnect_button = tk.Button(frame, text="断开 Telnet", font=("Arial", 12, "bold"), fg="white",bg="#46C0FB", command=self.disconnect_telnet, state=tk.DISABLED)self.disconnect_button.pack(side=tk.LEFT, padx=3)# 绑定获取焦点和失去焦点事件,显示和隐藏提示语self.host_addr_entry.bind("<FocusIn>", self.on_host_entry_focus_in)self.host_addr_entry.bind("<FocusOut>", self.on_host_entry_focus_out)# 创建一个输入框控件,并放置在Frame中,同时设置右侧空开3个空格self.command_entry = tk.Entry(frame, width=50, font=("Arial", 12, "bold"))self.command_entry.insert(0, "请发送指令...")self.command_entry.config(fg="gray")self.command_entry.pack(side=tk.LEFT, padx=12)# 绑定获取焦点和失去焦点事件,显示和隐藏提示语self.command_entry.bind("<FocusIn>", self.on_entry_focus_in)self.command_entry.bind("<FocusOut>", self.on_entry_focus_out)# 创建执行按钮控件,并放置在Frame中,右侧空开3个空格self.execute_button = tk.Button(frame, text="执行命令", font=("Arial", 12, "bold"), fg="white",bg="#46C0FB", command=self.execute_command, state=tk.DISABLED)self.execute_button.pack(side=tk.LEFT)self.telnet_client = Noneself.receive_thread = Nonedef on_host_entry_focus_in(self, event):if self.host_addr_entry.get() == "请输入主机地址...":self.host_addr_entry.delete(0, tk.END)self.host_addr_entry.config(fg="black")def on_host_entry_focus_out(self, event):if self.host_addr_entry.get() == "":self.host_addr_entry.insert(0, "请输入主机地址...")self.host_addr_entry.config(fg="gray")def on_entry_focus_in(self, event):if self.command_entry.get() == "请发送指令...":self.command_entry.delete(0, tk.END)self.command_entry.config(fg="black")def on_entry_focus_out(self, event):if self.command_entry.get() == "":self.command_entry.insert(0, "请发送指令...")self.command_entry.config(fg="gray")def connect_telnet(self):host = self.host_addr_entry.get() # 获取输入框内的主机地址port = 23             # 默认telnet端口username = 'root'     # 登录用户名password = '123456'   # 登录密码try:# 连接Telnet服务器self.telnet_client = telnetlib.Telnet(host, port, timeout=5)self.console_text.insert(tk.END, "成功连接到Telnet服务器。\n", "bold_tag")self.connect_button.config(state=tk.DISABLED)self.disconnect_button.config(state=tk.NORMAL)self.execute_button.config(state=tk.NORMAL)# 输入登录用户名self.telnet_client.read_until(b'login:')self.telnet_client.write(username.encode('ascii') + b"\n")# 输入登录密码self.telnet_client.read_until(b'Password:')self.telnet_client.write(password.encode('ascii') + b"\n")print('成功登录到设备:' + host)# 启动后台信息接收线程self.receive_thread = threading.Thread(target=self.receive_background_info)self.receive_thread.start()except Exception as e:self.console_text.insert(tk.END, f"连接失败: {e}\n", "bold_tag")def disconnect_telnet(self):if self.telnet_client:self.telnet_client.close()self.console_text.insert(tk.END, "已断开Telnet连接。\n", "bold_tag")self.connect_button.config(state=tk.NORMAL)self.disconnect_button.config(state=tk.DISABLED)self.execute_button.config(state=tk.DISABLED)def execute_command(self):command = self.command_entry.get() + "\n"self.telnet_client.write(command.encode('ascii'))self.command_entry.delete(0, tk.END)def receive_background_info(self):while True:try:output_data = self.telnet_client.read_very_eager().decode('utf-8')if output_data:clean_color_data = self.remove_color_codes(output_data.strip())self.console_text.insert(tk.END, clean_color_data, "bold_tag")# self.console_text.see(tk.END)time.sleep(0.5)except EOFError:breakexcept Exception as e:self.console_text.insert(tk.END, f"错误: {e}\n", "bold_tag")breakdef remove_color_codes(self, data):# 使用正则表达式匹配ANSI转义码,并替换为空字符串ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')return ansi_escape.sub('', data)if __name__ == "__main__":tenelt_tool = TeneltTool()tenelt_tool.window.mainloop()

4. Telnet 客户端效果展示 

5. 总结

由于这个工具是匆忙之间创作的,所以还存在一些缺陷,大家如果感兴趣,就拷贝源码自行优化吧。 

好啦,本章内容到此结束,感谢大家的热爱与支持~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/122892.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序如何上传微信聊天记录的文件

wx.chooseMessageFile({count: 10,type: image,success (res) {// tempFilePath可以作为img标签的src属性显示图片const tempFilePaths res.tempFiles} })参数说明 回调函数说明

【区块链 | IPFS】浅谈 | IPFS数据存储原理

IPFS在数据存储方面采用的是分散式的文件存储,区别于HTTP协议的位置寻址,IPFS是基于内容寻址,当文件上传到IPFS节点存储时,节点会对文件进行Merkle DAG(默克尔有向无环图)的格式组织分块存储,在存储完毕后,文件将以Merkle DAG的根哈希数来表示该文件,用户可以从IPFS构…

TSUMU58CDT9-1显示器芯片方案

TSUMU58CDT9-1是用于LCD显示器的整体解决方案图形处理IC&#xff0c;面板分辨率高达WUXGA。它配置了高速集成三adc /PLL、集成DVI/HDMI接收器、高质量显示处理引擎、集成微控制器和支持LVDS面板接口格式的输出显示接口。TSUMU58CDT9-1支持一个灵活的可配置数字输入接口&#xf…

Ajax介绍、爬取案例实战 + MongoDB存储

Ajax介绍 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于在Web应用程序中实现异步通信的技术。它允许在不刷新整个网页的情况下&#xff0c;通过在后台与服务器进行数据交换&#xff0c;实时更新网页的一部分。Ajax的主要特点包括&#xff1a; 异步通…

Python Flask Web开发三:数据表的字段增加和删除

前言 在实际的开发中&#xff0c;数据表中的字段的增加和删除是很正常的操作&#xff0c;在运营的不断提需求下&#xff0c;这个修改的频率是很高的&#xff0c;那么在flask中如何进行字段的增加和删除呢&#xff1f;下面我来给大家讲讲 一、创建迁移脚本 使用数据库迁移工具…

C++内存管理(2)new、delete详解

目录 new operator&#xff08;new操作&#xff09; new类对象时加不加括号的差别 new工作任务 delete工作任务 new和delete 堆区空间操作&#xff08;对比malloc和free&#xff09; new和delete操作基本类型的空间 new和delete操作基本类型的数组 new和delete操作类的…

Qt开发_调用OpenCV(3.4.7)设计完成人脸检测系统

一、前言 近年来,人脸识别技术得到了广泛的应用,它可以在各种场景中实现自动化的人脸检测和识别,例如安防监控、人脸解锁、人脸支付等。 该项目的目标是设计一个简单易用但功能强大的人脸检测系统,可以实时从摄像头采集视频,并对视频中的人脸进行准确的检测和框选。通过…

0012Java程序设计-springboot基于微信小程序的校园智慧帮系统的设计与实现

摘要目录相关技术2.1 MySQL数据库2.2 SpringBoot框架2.3 uniapp框架2.4 B/S架构 系统设计系统实现开发环境 摘要 随着移动互联网高速发展&#xff0c;手机、移动智能终端设备在生活中有着越来越重要的地位。在高校推崇以人为本的今天&#xff0c;也逐渐重视“移动互联网”技术…

​7.1 项目1 学生通讯录管理:文本文件增删改查(C++版本)(自顶向下设计+断点调试) (A)​

C自学精简教程 目录(必读) 作业目标&#xff1a; 这个作业中&#xff0c;你需要综合运用之前文章中的知识&#xff0c;来解决一个相对完整的应用程序。 作业描述&#xff1a; 1 在这个作业中你需要在文本文件中存储学生通讯录的信息&#xff0c;并在程序启动的时候加载这些…

【Mycat1.6】缓存不生效问题处理

背景 系统做读写分离&#xff0c;有大量读需求&#xff0c;基本没有实时获取数据业务需要&#xff0c;所以可以启用缓存来减缓数据库压力&#xff0c;传统使用mybatis的缓存需要大量侵入式声明&#xff0c;所以结合需求使用Mycat中间件来满足 数据库结构 mysql-master&#…

渗透测试漏洞原理之---【业务安全】

文章目录 1、业务安全概述1.1业务安全现状1.1.1、业务逻辑漏洞1.1.2、黑客攻击目标 2、业务安全测试2.1、业务安全测试流程2.1.1、测试准备2.1.2、业务调研2.1.3、业务建模2.1.4、业务流程梳理2.1.5、业务风险点识别2.1.6 开展测试2.1.7 撰写报告 3、业务安全经典场景3.1、业务…

多维时序 | MATLAB实现GWO-BiLSTM灰狼算法优化双向长短期记忆神经网络的多变量时间序列预测

多维时序 | MATLAB实现GWO-BiLSTM灰狼算法优化双向长短期记忆神经网络的多变量时间序列预测 目录 多维时序 | MATLAB实现GWO-BiLSTM灰狼算法优化双向长短期记忆神经网络的多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现CNN-BiGRU-A…

手写Spring:第11章-容器事件和事件监听器

文章目录 一、目标&#xff1a;容器事件和事件监听器二、设计&#xff1a;容器事件和事件监听器三、实现&#xff1a;容器事件和事件监听器3.1 工程结构3.2 容器事件和事件监听器类图3.3 定义和实现事件3.3.1 定义事件抽象类3.3.2 定义应用上下文事件实现类3.3.3 上下文刷新事件…

如何将枯燥的大数据进行可视化处理?

在数字时代&#xff0c;大数据已经成为商业、科学、政府和日常生活中不可或缺的一部分。然而&#xff0c;大数据本身往往是枯燥的、难以理解的数字和文字&#xff0c;如果没有有效的方式将其可视化&#xff0c;就会错失其中的宝贵信息。以下是一些方法&#xff0c;可以将枯燥的…

基于SpringBoot的汽车租赁系统

基于SpringBootVue的汽车租赁系统&#xff0c;前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 角色&#xff1a;管理员、业务员、用户 管理员 用户管理…

STM32 软件IIC 控制OLED 显示屏

1. 硬件IIC 实在是太难用了&#xff0c;各种卡死&#xff0c;各种发不出来数据&#xff0c;没那么多时间折腾了&#xff0c;还是用软件IIC 先吧&#xff0c;初始化 void OLED_Software_IIC_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_AHBPeriphClockCmd(OLED_SOFTWARE…

Jmeter进阶使用指南-使用断言

Apache JMeter是一个流行的开源负载和性能测试工具。在JMeter中&#xff0c;断言&#xff08;Assertions&#xff09;是用来验证响应数据是否符合预期的一个重要组件。它是对请求响应的一种检查&#xff0c;如果响应不符合预期&#xff0c;那么断言会标记为失败。 以下是如何在…

Linux如何安装MySQL

Linux安装MySQL5.7 1、下载 官网下载地址&#xff1a;http://dev.mysql.com/downloads/mysql/ 2、复制下面几个文件 3、检查当前系统是否安装过mysql、检查当前mysql依赖环境、检查/tmp文件夹权限 1&#xff09;检查当前系统是否安装过mysql&#xff0c;执行安装命令前&am…

LabVIEW应用开发——LabVIEW2019保姆级介绍、安装、第一个程序

一、前言 LabVIEW是一种程序开发环境&#xff0c;由美国国家仪器&#xff08;NI&#xff09;公司研制开发&#xff0c;类似于C和BASIC开发环境&#xff0c;但是LabVIEW与其他计算机语言的显著区别是&#xff1a;其他计算机语言都是采用基于文本的语言产生代码&#xff0c;而Lab…

MyBatis配置及单表操作

文章目录 一. MyBatis概述二. MyBatis项目的创建1. 准备一个数据表2. 创建项目 三. MyBatis的使用1. 基本使用2. SpringBoot单元测试 四. 使用MyBatis实现单表操作1. 查询2. 修改3. 删除4. 新增 五. 基于注解完成SQL 一. MyBatis概述 MyBatis 是一款优秀的持久层框架&#xff…