-
2017-04-02 22:47:22最近项目有个需求,需要在APP端实现Telnet操作。本来网上Telnet手机终端相关的APP,但是和公司的要求有点不符合,所以只能苦逼的自己写啦。废话不说了,直接进入主题。
Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。要开始一个telnet会话,必须输入用户名和密码来登录服务器。Telnet是常用的远程控制Web服务器的方法(百度百科粘的)。
从上面可以看出,要想远程操作服务器,必须需要先进行连接和登录,然后通过相应的指令去操作服务器。那怎样进行连接呢?Apache给我们提供相关jar包(commons-net-3.3.jar),TelnetClient是commons-net-3.3.jar下的一个类,用于实现telnet连接。具体见代码:
/** *Telnet操作类 * Created by fblife on 2017/3/28. */ public class TelnetUtils { private static final String TAG = TelnetUtils.class.getSimpleName(); private TelnetClient client; private BufferedInputStream bis; private PrintStream ps; private char prompt = '$'; private GetMessageListener mListener; public TelnetUtils() { client = new TelnetClient(); } /** * 连接及登录 * @param ip 目标主机IP * @param port 端口号(Telnet 默认 23) * @param user 登录用户名 * @param password 登录密码 */ public void connect(String ip, int port, String user, String password) { try { client.connect(ip, port); bis = new BufferedInputStream(client.getInputStream()); ps = new PrintStream(client.getOutputStream()); this.prompt = user.equals("root") ? '#' : '$'; login(user, password); } catch (Exception e) { e.printStackTrace(); } } /** * 登录 * @param user * @param password */ public void login(String user, String password) { read("login:"); write(user); read("Password:"); write(password); read(prompt + " "); } /** * 读取返回来的数据 * @param info * @return */ public String read(String info) { try { char lastChar = info.charAt(info.length() - 1); StringBuffer sb = new StringBuffer(); char ch = (char) bis.read(); while (true) { sb.append(ch); if (ch == lastChar) { if (sb.toString().endsWith(info)) { if (mListener != null){ mListener.onMessage(sb.toString()); } return sb.toString(); } } ch = (char) bis.read(); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 写指令 * @param instruction */ public void write(final String instruction) { try { ps.println(instruction); ps.flush(); } catch (Exception e) { e.printStackTrace(); } } /** * 向目标发送命令字符串 * @param command * @return */ public String sendCommand(String command) { try { write(command); return read(prompt + " "); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 关闭连接 */ public void disconnect() { try { if (client != null) client.disconnect(); if (in != null) in.close(); if (ps != null) ps.close(); } catch (Exception e) { e.printStackTrace(); } } public interface GetMessageListener{ void onMessage(String info); } public void setListener(GetMessageListener mListener) { this.mListener = mListener; } }
Activivty 中代码比较简单,但是需要注意的是:Telnet的相关操作都需要在子线程中去操作。代码如下:
public class CameraConfigActivity extends BaseActivity implements TelnetUtils.GetMessageListener, View.OnClickListener { private static final String TAG = CameraConfigActivity.class.getSimpleName(); private Context mContext; private TelnetUtils telnet; private TextView tv_mess; private ExecutorService singleThreadExecutor; private EditText ed_send; private Button bu_send; private InputMethodManager imm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); mContext = this; initView(); singleThreadExecutor = Executors.newFixedThreadPool(3); imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); } private void initView() { tv_mess = (TextView) findViewById(R.id.tv_mess); ed_send = (EditText) findViewById(R.id.ed_send); bu_send = (Button) findViewById(R.id.bu_send); bu_send.setOnClickListener(this); } @Override protected void onResume() { super.onResume(); telnet = new TelnetUtils(); telnet.setListener(this); singleThreadExecutor.execute(new Runnable() { @Override public void run() { telnet.connect("192.168.21.100", 23, "root", "123"); } }); } @Override public void onMessage(final String info) { runOnUiThread(new Runnable() { @Override public void run() { if (info != null){ String s = tv_mess.getText().toString(); tv_mess.setText(s + "\n" + info); } } }); } @Override protected void onDestroy() { super.onDestroy(); telnet.disconnect(); singleThreadExecutor.shutdown();//关闭线程 } @Override public void onClick(View v) { final String send = ed_send.getText().toString(); imm.hideSoftInputFromWindow(ed_send.getWindowToken(),0); ed_send.setText(""); singleThreadExecutor.execute(new Runnable() { @Override public void run() { if (send == null) return; telnet.sendCommand(send); } }); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ finish(); return true; } return super.onKeyDown(keyCode, event); } }
三个对文件操作的Linux指令:
chmod u+x 文件名 修改文件的权限。
echo -e "写入文件的内容" > 文件名 把内容写入文件(覆盖原有内容)。
echo -e "写入文件的内容" >> 文件名 把内容写入文件(追加在原有内容后面)。
sed -i '45c "修改的内容" ' 文件名 替换文件某一行的内容(需要加上 -i,否则不会修改文件,只写入到内存中)。
更多相关内容 -
6、TELNET终端设计与实现
2021-07-13 15:32:536、TELNET终端设计与实现 二、设计内容 设计一个 TELNET 终端程序。 三、设计步骤 3.1原理分析 Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上...一、设计题目
6、TELNET终端设计与实现
二、设计内容
设计一个 TELNET 终端程序。
三、设计步骤
3.1原理分析
Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。
基本工作过程如下:
1)本地与远程主机建立连接。该过程实际上是建立一个TCP连接,用户必须知道远程主机的Ip地址或域名;
2)将本地终端上输入的用户名和口令及以后输入的任何命令或字符以NVT(Net Virtual Terminal)格式传送到远程主机。该过程实际上是从本地主机向远程主机发送一个IP数据包;
3)将远程主机输出的NVT格式的数据转化为本地所接受的格式送回本地终端,包括输入命令回显和命令执行结果;
4)最后,本地终端对远程主机进行撤消连接。该过程是撤销一个TCP连接。
3.2编程设计
1,一般步骤
- 创建WSADATA
- 选择dll版本
- Winsock服务初始化
- 找到可用Winsock DLL
- 创建远程连接
2,客户端:
- 创建socket
- 连接服务器地址
- 持续发送命令
3,服务器端:
- 创建socket
- 绑定socket
- 监听
- 处理连接请求
- 接收命令并执行
关键代码
寻找Winsock.dll
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return -1;
}
本地主机:数据发送与意外情况分析:
printf("Please input the command you want to send \n");
scanf("%s",sz_send_info);
iRet=send(client, (char*)sz_send_info, sizeof(sz_send_info), 0);
if (iRet!=SOCKET_ERROR)
{
printf("send successfully\n");
}
else
{
printf("failed to send");
}
远程主机:数据获取与命令执行
iRet = recv(client, szInfo, 1013, 0);
if (0 >= iRet)
{
continue;
}
else
{
system(szInfo); //开始进行数据处理
iRet = -1;
}
程序流程图
6,Telnet main 6,Telnet CreateServerSocket
6,Telnet CreateClientSocket
四、调试过程
关于远程控制的问题,自己一开始没想明白需要运用哪个函数。后来借助System,倒是加以解决。
五、结果及分析
本地主机分别输入ipconfig(查看IP地址)和Write(打开写字板)
远程主机的反馈:
1)执行ipconfig
2)执行write
六、心得体会
远程控制,对控制者的计算机水平倒也有一定的要求,如基本的命令行语句。
客户端发起控制请求:
#include <winsock2.h> #include <iostream> #include <windows.h> #pragma comment(lib, "ws2_32.lib") bool CreateClientSocket() { BOOL bRet = FALSE; do { //1、创建套接字 SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == client) { SetLastError(WSAGetLastError()); break; } //2、连接服务器socke地址 sockaddr_in server_addr = { 0 }; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(28888); //htons:将参数转换成TCP/IP字节序列 server_addr.sin_addr.S_un.S_addr = inet_addr("192.168.43.111");//IP地址//10.11.50.111 虚拟机:192.168.48.128 if (SOCKET_ERROR == connect(client, (sockaddr*)&server_addr, sizeof(server_addr))) { SetLastError(WSAGetLastError()); break; } //3、发送数据 char sz_send_info[1024] = { 0 }; int iRet = 0; while (1) { printf("Please input the command you want to send \n"); //std::cin >> sz_send_info; scanf("%s",sz_send_info); iRet=send(client, (char*)sz_send_info, sizeof(sz_send_info), 0); if (iRet!=SOCKET_ERROR) { printf("send successfully\n"); } else { printf("failed to send"); } } bRet = TRUE; } while (FALSE); return bRet; } int main() { WORD wVersionRequested; WSADATA wsaData; int err; /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("WSAStartup failed with error: %d\n", err); return -1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { /* Tell the user that we could not find a usable */ /* Winsock DLL. */ printf("Could not find a usable version of Winsock.dll\n"); WSACleanup(); return -1; } if (FALSE == CreateClientSocket()) { //printf("CreateClientSocket failed with error: %d\n", GetLastError()); return -1; } system("pause"); WSACleanup(); return 0; }
服务器端接收请求:
// #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <winsock2.h> #include <iostream> #include<windows.h> #pragma comment(lib, "ws2_32.lib") bool CreateServerSocket() { BOOL bRet=FALSE; do { //1、创建套接字 SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET== server) { SetLastError(WSAGetLastError()); break; } //2、绑定Socket到本地 sockaddr_in server_addr = {0}; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(28888); //htons:将参数转换成TCP/IP字节序列 server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//以主机进行测试 if (SOCKET_ERROR == bind(server, (sockaddr*)&server_addr, sizeof(server_addr))) { SetLastError(WSAGetLastError()); break; } //3、监听 if (SOCKET_ERROR == listen(server, 10)) { SetLastError(WSAGetLastError()); break; } //4、处理连接请求 sockaddr_in client_addr = {0}; int len = sizeof(client_addr); SOCKET client=accept(server, (sockaddr*)&client_addr, &len); if (INVALID_SOCKET == client) { SetLastError(WSAGetLastError()); break; } //5、接受数据 char szInfo[1024] = { 0 }; int iRet=-1; while (1) { iRet = recv(client, szInfo, 1013, 0); if (0 >= iRet) { continue; } else { system(szInfo); //开始进行数据处理 iRet = -1; } } bRet = TRUE; } while (FALSE); return bRet; } int main() { WORD wVersionRequested; WSADATA wsaData; int err; /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { /* Tell the user that we could not find a usable */ /* Winsock DLL. */ printf("WSAStartup failed with error: %d\n", err); return -1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("Could not find a usable version of Winsock.dll\n"); WSACleanup(); return -1; } if (FALSE==CreateServerSocket()) { //printf("CreateServerSocket failed with error: %d\n",GetLastError()); return -1; } system("pause"); WSACleanup(); return 0; }
-
RFC930_Telnet终端类型选项.doc
2019-08-22 15:10:10Telnet终端类型选项 (RFC930——Telnet Terminal Type Option) 本备忘录的状态 本RFC规范了一个ARPA Internet community上的标准。在ARPA Internet上的所有主机应当采用和实现这个标准。本文的发布不受任何限制... -
计算机网络课程设计之TELNET 终端设计与实现
2022-01-15 15:08:41Telnet Windows前言
Telnet设计是一个比较麻烦的东东,因为Telnet服务器需要部署,而且网络上的资料比较少,最后通过在云服务器CentOS上安装Telnet服务器然后自己的程序作为一个Telnet客户端测试成功,记录结果,重点测试过程放在总体设计中 附录附上Telnet码
参考博客:
https://www.cnblogs.com/suni/p/11528480.html
https://www.cnblogs.com/image-eye/archive/2012/03/28/2421726.html白嫖容易,创作不易,本文原创,转载请注明!!!
源码和可运行程序:
链接:https://pan.baidu.com/s/1A9KctmpP2JJgyW2wLrehIg
提取码:Lin2计算机网络课程设计:
计算机网络课程设计之网络聊天程序的设计与实现
计算机网络课程设计之Tracert与Ping程序设计与实现
计算机网络课程设计之基于 IP 多播的网络会议程序
计算机网络课程设计之网络嗅探器的设计与实现
计算机网络课程设计之电子邮件客户端程序设计与实现
计算机网络课程设计之TELNET 终端设计与实现
计算机网络课程设计之网络代理服务器的设计与实现
计算机网络课程设计之简单 Web Server 程序的设计与实现Qt入门系列:
Qt学习之C++基础
Qt学习之Qt安装
Qt学习之Qt基础入门(上)
Qt学习之Qt基础入门(中)
Qt学习之Qt基础入门(下)创作不易,整个课程设计程序3000多行代码,所有实验都写在了一个程序中,时间有限,能力不足,转载望注明!!!
本文链接
个人博客:https://ronglin.fun/archives/274
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/122510563实验题目
TELNET 终端设计与实现
实验目的
参照 RFC854、RFC855 文档,设计一个 TELNET 终端程序。
总体设计
(含背景知识或基本原理与算法、或模块介绍、设计步骤等)
安装Telnet
首先在自己的云服务器上安装Telnet,没有云服务器怎么办呢
安装Linux虚拟机,然后把虚拟机的ip穿透到主机上,虚拟机和主机能实现相互通信即可,然后要记得防火墙开放Telnet默认的23端口
为了方便,我这里直接用自己的云服务器,就免去了ip穿透的过程,注意要在安全组中开发23端口
在CentOS终端中输入yum install xinetd yum install telnet yum install telnet-server
telnet默认不开启,修改文件/etc/xinetd.d/telnet来开启服务 修改 disable = yes 为 disable = no
如果 telnet文件不存在可以手动创建 添加以下内容service telnet { flags = REUSE socket_type = stream wait = no user = root server =/usr/sbin/in.telnetd log_on_failure += USERID disable = no }
启动Telnet 查看运行
service xinetd restart ps -ef | grep telnet
Telnet客户端设计
准备工作做好,然后就是根据协议设计Telnet
要更好地理解Telnet数据类型,我们用一个网络调试助手,直接用TCP连接Telnet服务端,看看返回什么格式,如下图:
可以看到服务器返回了一段十六进制代码FF FD 18 FF FD 20 FF FD 23 FF FD 27
然后根据博客
https://www.cnblogs.com/image-eye/archive/2012/03/28/2421726.html
博客中有对应的命令解释
我们做出如下理解
Telnet连接之后,服务器会与客户端"协商",例如:FF FD 18
一个Telnet命令由三部分构成,第一个是IAC 固定值为0xFF,表示是一个Telnet,第二部分是命令码,这里是0xFD,表达的是DO,意为认可选项请求,第三部分为选项码,这里是18,表示18号功能(查文档可以知道18号功能对应什么功能)
这句话的意思是,服务器:我想要求18号功能
然后客户端就要回应,我这里回应的是FF FC 18
,意为客户端拒绝你的请求,拒绝18号功能
其他命令同理。
我们看一段我人为联系认证的过程[2022-01-05 21:15:35.681]# RECV HEX> FF FD 18 FF FD 20 FF FD 23 FF FD 27 [2022-01-05 21:15:47.899]# SEND HEX> FF FC 18 FF FC 20 FF FC 23 FF FC 27 [2022-01-05 21:15:47.970]# RECV HEX> FF FB 03 FF FD 01 FF FD 1F FF FB 05 FF FD 21 [2022-01-05 21:16:14.162]# SEND HEX> FF FE 03 FF FC 01 FF FC 1F FF FE 05 FF FC 21 [2022-01-05 21:16:14.220]# RECV HEX> FF FB 03 FF FB 01 0D 0A 4B 65 72 6E 65 6C 20 33 2E 31 30 2E 30 2D 31 31 36 30 2E 34 35 2E 31 2E 65 6C 37 2E 78 38 36 5F 36 34 20 6F 6E 20 61 6E 20 78 38 36 5F 36 34 0D 0A [2022-01-05 21:16:14.327]# RECV HEX> 4C 69 6E 4C 69 6E 20 6C 6F 67 69 6E 3A 20
可以看到,在最后的接收数据中,
[2022-01-05 21:16:14.220]# RECV HEX>
这条数据FF FB 01
结束之后,就是其他数据了,就是ASCII码了,我们用工具翻译一下Kernel 3.10.0-1160.45.1.el7.x86_64 on an x86_64 LinLin login:
可以看到"协商"完成
详细设计
(含主要的数据结构、程序流程图、关键代码等)
这样就好理解了,主要就是TCP连接,然后用代码和Telnet服务器"协商",协商完成之后,直接用TCP做数据交互即可
连接TCP服务器//ip为远程服务器的地址 default_port = 23 socket->connectToHost(this->ip,this->default_port);
然后就是和服务器协商代码,我这里为了方便,将服务器的所有请求命令全部拒绝
QByteArray MyTelnet::response(QByteArray data) { //FF FD 18 -> FF FC 18 QByteArray result; result.resize(data.size()); for(int i=0;i<data.size();++i) //所有请求都不允许 { if(data[i] == 0xFE) //DONT -- WONT 发送者希望对方使某选项无效,接收者必须接受该请求 { result[i] = 0xFC; } else if(data[i] == 0xFC) //WONT -- DONT 发送者希望某选项无效,接收者必须接受该请求 { result[i] = 0xFE; } else if(data[i] == 0xFD) //DO -- DONT 发送者希望接收者激活某选项 接收者拒绝请求 { result[i] = 0xFC; } else if(data[i] == 0xFB) //WILL -- DONT 发送者想激活某功能 接收者拒绝该选项 { result[i] = 0xFE; } else { result[i] = data[i]; } } qDebug()<<"result: "<<result; return result; }
然后需要注意的是,有些TCP传回来的数据,是既有Telnet命令也有ASCII数据的,例如上边
[2022-01-05 21:16:14.220]# RECV HEX>
这条数据,就既有命令,也有数据,因此我写了两个函数用来分离命令和数据,大概代码如下QByteArray data = socket->readAll(); qDebug()<<data; int result_write = -1; if(data.contains((char)(0xFF))) //命令 { //endIACIndex()函数用来寻找最后一个0xFF的位置 int IAC_index = endIACIndex(data); if(data.size() - IAC_index-1 >2) //有命令也有数据 { //截取命令部分,发送数据给服务器进行互交 result_write = socket->write(response(QByteArray(data).mid(0,IAC_index+3))); //\xFF\xFB\x03\xFF\xFB\x01\r\nKernel //删除前边的命令和\r\n //截取数据部分,将数据发送给前端界面显示 emit this->sendData(QByteArray(data).right(data.size()-(IAC_index+4+1))); } else { //发送数据给服务器进行互交 result_write = socket->write(response(data)); } } else { //将数据发送给前端界面显示 emit this->sendData(data); }
然后的数据就都是ASCII码了
实验结果与分析
运行程序
输入自己云服务器的域名,如果是虚拟机的话,输入虚拟机的穿透成功之后的ip
点击连接,然后登录验证,然后输入ls /
和ls
命令查看效果
可以看到命令可用,成功小结与心得体会
对Telnet有了更深入的理解,同时对于基于TCP的协议也有了更深入的理解,当遇到一个基于TCP的协议的时候,可以先用最普通的TCP连接查看数据格式,然后根据开放的协议文档研究,获益匪浅
=w=附
文本数据
//命令码: 一系列定义:(最常用的250-254) const unsigned char IAC = 0xFF; //命令解释符.每条指令的前缀 255 const unsigned char DONT = 0xFE; //拒绝选项请求 254 const unsigned char DO = 0xFD; //认可选项请求 253 const unsigned char WONT = 0xFC; //拒绝启动选项 252 const unsigned char WILL = 0xFB; //同意启动(enable)选项 251 const unsigned char SB = 0xFA; //子选项开始 250 const unsigned char GA = 0xF9; //继续进行 const unsigned char EL = 0xF8; //删除行 const unsigned char EC = 0xF7; //转义字符 const unsigned char AYT = 0xF6; //对方是否还在运行? const unsigned char AO = 0xF5; //异常中止输出 const unsigned char IP = 0xF4; //中断进程 const unsigned char BRK = 0xF3; //中断 const unsigned char DM = 0xF2; //数据标记 const unsigned char NOP = 0xF1; //无操作 const unsigned char SE = 0xF0; //自选项结束 const unsigned char EOR = 0xEF; //记录结束符 const unsigned char ABORT = 0xEE; //异常中止进程 const unsigned char SUSP = 0xED; //挂起当前进程(作业控制) const unsigned char eof = 0xEC; //文件结束符 //1)WILL:发送方本身将激活选项 //2)DO:发送方想叫接受端激活选项 //3)WONT:发送方本身想禁止选项 //4)DONT:发送方想让接受端去禁止选项 //WILL -- DO 发送者想激活某功能 接收者接受该选项 //WILL -- DONT 发送者想激活某功能 接收者拒绝该选项 //DO -- WILL 发送者希望接收者激活某选项 接收者接受请求 //DO -- DONT 发送者希望接收者激活某选项 接收者拒绝请求 //WONT -- DONT 发送者希望某选项无效,接收者必须接受该请求 //DONT -- WONT 发送者希望对方使某选项无效,接收者必须接受该请求 //选项码 //1-回显 //3-抑制继续进行 //5-状态 //6-定时标记 //24-终端类型 //31-窗口大小 //32-终端速度 //33-远程流量控制 //34-行方式 //36-环境变量 //FF FD 18 FF FD 20 FF FD 23 FF FD 27 //255 253 24 :DO 终端类型 //255 253 32 :DO 终端速度 //255 253 35 :DO 行方式 //255 253 39 //[2022-01-05 21:15:35.681]# RECV HEX> //FF FD 18 FF FD 20 FF FD 23 FF FD 27 //[2022-01-05 21:15:47.899]# SEND HEX> //FF FC 18 FF FC 20 FF FC 23 FF FC 27 //[2022-01-05 21:15:47.970]# RECV HEX> //FF FB 03 FF FD 01 FF FD 1F FF FB 05 FF FD 21 //[2022-01-05 21:16:14.162]# SEND HEX> //FF FE 03 FF FC 01 FF FC 1F FF FE 05 FF FC 21 //[2022-01-05 21:16:14.220]# RECV HEX> //FF FB 03 FF FB 01 0D 0A 4B 65 72 6E 65 6C 20 33 2E 31 30 2E 30 2D 31 31 36 30 2E 34 35 2E 31 2E 65 6C 37 2E 78 38 36 5F 36 34 20 6F 6E 20 61 6E 20 78 38 36 5F 36 34 0D 0A //[2022-01-05 21:16:14.327]# RECV HEX> //4C 69 6E 4C 69 6E 20 6C 6F 67 69 6E 3A 20
-
sockterm:使用Socket.IO实现的基于Web的sshtelnet终端
2021-05-25 05:20:46短期 使用Socket.IO实现的基于Web的ssh / telnet终端。 -
telnet终端和服务器制作程序
2019-01-06 17:37:48这是一个telnet终端和服务器制作程序资料,可以使用该资料。 -
vc Telnet终端源程序
2011-04-08 17:32:51Telnet终端源程序 Telnet终端源程序 Telnet终端源程序 -
TELNET 终端设计与实现 python实现 计算机网络课程设计
2020-01-17 21:28:00参照 RFC854、RFC855 文档,设计一个 TELNET 终端程序。 telnet协议 详见 telnet协议详解 代码 import selectors import socket import sys __all__ = ["Telnet"] DEBUGLEVEL = 0 TELNET_PORT = 23 # Telnet ...设计内容
参照 RFC854、RFC855 文档,设计一个 TELNET 终端程序。
telnet协议 详见
telnet协议详解
代码
import selectors import socket import sys __all__ = ["Telnet"] DEBUGLEVEL = 0 TELNET_PORT = 23 # Telnet protocol characters (don't change) IAC = bytes([255]) DONT = bytes([254]) DO = bytes([253]) WONT = bytes([252]) WILL = bytes([251]) theNULL = bytes([0]) SE = bytes([240]) SB = bytes([250]) # Telnet protocol options code (don't change) ECHO = bytes([1]) # echo NOOPT = bytes([0]) if hasattr(selectors, 'PollSelector'): _TelnetSelector = selectors.PollSelector else: _TelnetSelector = selectors.SelectSelector class Telnet: def __init__(self, host=None, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.host = host self.port = port self.timeout = timeout self.sock = None self.rawq = b'' self.irawq = 0 self.cookedq = b'' self.eof = 0 self.iacseq = b'' # Buffer for IAC self.sb = 0 # flag for SB and SE self.sbdataq = b'' self.option_callback = None if host is not None: self.open(host, port, timeout) def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.eof = 0 if not port: port = TELNET_PORT self.host = host self.port = port self.timeout = timeout self.sock = socket.create_connection((host, port), timeout) def __del__(self): self.close() def close(self): sock = self.sock self.sock = None self.eof = True self.iacseq = b'' self.sb = 0 if sock: sock.close() def get_socket(self): return self.sock def fileno(self): return self.sock.fileno() def write(self, buffer): if IAC in buffer: buffer = buffer.replace(IAC, IAC + IAC) self.sock.sendall(buffer) def read_eager(self): self.process_rawq() while not self.cookedq and not self.eof and self.sock_avail(): self.fill_rawq() self.process_rawq() return self.read_very_lazy() def read_very_lazy(self): buf = self.cookedq self.cookedq = b'' if not buf and self.eof and not self.rawq: raise EOFError('telnet connection closed') return buf def process_rawq(self): buf = [b'', b''] try: while self.rawq: c = self.rawq_getchar() if not self.iacseq: if c == theNULL: continue if c == b"\021": continue if c != IAC: buf[self.sb] = buf[self.sb] + c continue else: self.iacseq += c elif len(self.iacseq) == 1: # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]' if c in (DO, DONT, WILL, WONT): self.iacseq += c continue self.iacseq = b'' elif len(self.iacseq) == 2: cmd = self.iacseq[1:2] self.iacseq = b'' opt = c if cmd in (DO, DONT): self.sock.sendall(IAC + WONT + opt) elif cmd in (WILL, WONT): self.sock.sendall(IAC + DONT + opt) except EOFError: # raised by self.rawq_getchar() self.iacseq = b'' # Reset on EOF self.sb = 0 pass self.cookedq = self.cookedq + buf[0] self.sbdataq = self.sbdataq + buf[1] def rawq_getchar(self): if not self.rawq: self.fill_rawq() if self.eof: raise EOFError c = self.rawq[self.irawq:self.irawq + 1] self.irawq = self.irawq + 1 if self.irawq >= len(self.rawq): self.rawq = b'' self.irawq = 0 return c def fill_rawq(self): if self.irawq >= len(self.rawq): self.rawq = b'' self.irawq = 0 buf = self.sock.recv(50) # self.msg("recv %r", buf) self.eof = (not buf) self.rawq = self.rawq + buf def sock_avail(self): with _TelnetSelector() as selector: selector.register(self, selectors.EVENT_READ) return bool(selector.select(0)) def mt_interact(self): import _thread _thread.start_new_thread(self.listener, ()) while 1: line = sys.stdin.readline() if not line: break self.write(line.encode('ascii')) def listener(self): while 1: try: data = self.read_eager() except EOFError: print('*** Connection closed by remote host ***') return if data: sys.stdout.write(data.decode('ascii')) else: sys.stdout.flush() def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() def test(): host = '******' # 远程服务器centos的ip 远程服务器需要先安装telnet服务并且运行 port = 23 with Telnet() as tn: tn.open(host, port, timeout=0.5) tn.mt_interact() if __name__ == '__main__': test()
-
一种将程序的标准输出重定向到telnet终端的方法
2016-09-29 11:58:10在现场调试嵌入式设备时,很多时候我们是无法连接串口查看打印信息的,只可以通过网络连接telnet登陆到设备终端, 而此时是无法查看当前运行的应用程序的打印信息的,为我们排查问题带来了一定的困难。当然,我们... -
telnet(超级终端)
2012-10-22 17:51:55正对xp的超级终端被无辜杀掉,可以用此软件代替 非常好用,非常小 -
TELNET终端机
2011-10-27 20:25:12这是一个TELNET终端机使用工具,由本人提供的另外一个C++代码"49490142Telnet.rar"配套使用 -
Telnet终端源程序
2011-10-27 20:21:26Telnet终端源程序,非常好用.供大家参考 -
telnet终端NT32423
2012-05-10 11:08:40经常用到的telnet终端NT32423 -
Scrapy 内置 Telnet 终端(Telnet Console)
2018-10-18 10:18:19Scrapy 提供了内置的 Telnet 终端,以供检查,控制 Scrapy 运行的进程;Telnet 仅仅是一个运行在 Scrapy 进程中的普通 Python 终端;该扩展默认为启用,不过你也可以关闭。 如何访问: Telnet 终端监听设置中定义的... -
mini telnet 终端管理系统
2011-04-14 22:01:06LINUX C socket程序 通过I/O费用 seLINUX C socket程序 通过I/O费用 select lect -
TELNET终端类型选项
2013-09-30 16:21:00转:http://www.cnpaf.net/Class/Telnet/200408/5.html 1. 命令名称及编号TERMINAL-TYPE242.命令含义IACWILLTERMINAL-TYPE发送者希望在接下来的子选项协商中发送终端类型信息。IACWON'TTERMINAL-TYPE发送者... -
C++实现telnet动态调试模块:将日志输出到telnet终端,通过telnet终端调用自定义注册的函数
2022-06-29 19:01:31telnet动态调试模块:将日志输出到telnet终端,通过telnet终端调用自定义注册的函数 -
连接到linux系统,SSH,telnet终端中文显示乱码
2009-08-12 15:52:23详细解决方法请参见附件:连接到linux系统,SSH,telnet终端中文显示乱码. -
Telnet终端类型选项
2007-07-28 07:58:00Telnet终端类型选项 (RFC930——Telnet Terminal Type Option) 本备忘录的状态 本RFC规范了一个ARPA Internet community上的标准。在ARPA Internet上的所有主机应当采用和实现这个标准。本文的发布不受任何... -
不能使用SSH和TELNET终端故障的排查
2018-09-12 10:21:02[不能使用SSH和TELNET终端故障的排查 ] 问题描述: 经王世龙王工反馈,尝试使用SSH和telnet终端连接不上的情况,并描述过程中修改过一些参数,怀疑是某些参数有问题。因为排查中发现端口22的网络是可用的... -
gtermix gtk+ telnet client-开源
2021-05-02 05:01:01gtermix是用于呼叫BBS的gtk + telnet客户端。 它利用自定义的VGA文本模式模拟终端小部件,使其能够像在DOS终端程序中一样准确地呈现公告板系统。 -
计算机网络 远程终端协议 TELNET
2020-12-14 18:13:54TELNET 是一个简单的远程终端协议(又称终端仿真协议),也是互联网的正式标准。 用户用 TELNET 就可在其所在地通过 TCP 连接注册(即登录)到远地的另一个主机上(使用主机名或 IP 地址)。 TELNET 能将用户的击键... -
爬虫:Scrapy - Telnet 终端(Telnet Console)
2017-01-13 11:31:00Telnet 终端监听设置中定义的 TELNETCONSOLE_PORT,默认为 6023,访问 telnet 请输入: telnet localhost 6023 >>> Windows 及大多数 Linux 发行版都自带了所需的 telnet 程序。 telnet 终端中可用的变量... -
解决telnet终端乱码的问题
2009-11-24 13:34:00我用的secureCRT,telnet到suse服务器上。secureCRT不能显示中文,出现乱码,在会话选项里面把字符编码改成utf-8还是不行。在网上搜了一下,试了两种方法,确实可行。1.用putty这个客户端,然后在软件左边设置Window... -
已经运行的程序,如何修改重定向输出到指定的telnet终端
2020-12-19 15:13:13网上查了大部分都是用代码实现的,我尝试了在telnet终端窗口输入 命令格式: 运行程序的完整路径 >> file路径 执行完之后,串口控制台还是有程序的printf信息,而file路径下只有部分信息,我这是哪里出了... -
telnet 客户终端 实例 源码
2010-03-31 17:47:50telnet 客户终端 实例 源码telnet 客户终端 实例 源码 -
在 ssh , telnet 终端中文显示乱码解决办法
2017-07-01 11:26:43#vi /etc/sysconfig/i18n 将原内容 LANG="en_US.UTF-8" SYSFONT="latarcyrheb-sun16" 修改为 LANG="zh_CN.GB18030" LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN" SUPPORTED="zh_... -
超级终端的telnet功能 和 Putty的telnet功能
2018-04-16 15:33:17win7 64位下 ,从别的地方下载的 超级终端:\safe_software\develop_tool\超级终端ZhongDuan_V1.01_XiTongZhiJia\windows 7 超级终端 v1.01 绿色版\hypertrm.exe运行该软件: 注意图中的设置,关于回显和发送附加... -
ZOC Terminal 7.23.3 特别版 Mac 强大的SSH/Telnet终端工具
2019-04-14 00:36:06它支持ANSI, VT52, VT100, VT102, VT220, IBM 3270 和Secure Shell 等等,而且功能相当的丰富,而且它是一款以出色的配置和简洁的用户界面而闻名的功能强大且行之有效的终端模拟器和telnet客户端。我推荐有需要的... -
爬虫:Scrapy14 - Telnet 终端(Telnet Console)
2016-09-19 10:03:00Scrapy 提供了内置的 Telnet 终端,以供检查,控制 Scrapy 运行的进程。Telnet 仅仅是一个运行在 Scrapy 进程中的普通 Python 终端。因此你可以在其中做任何是。 Telnet 终端是一个自带的 Scrapy 扩展。该扩展默认...