计算机网络课程设计之TELNET 终端设计与实现
前言
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終端中輸入
telnet默認不開啟,修改文件/etc/xinetd.d/telnet來開啟服務 修改 disable = yes 為 disable = no
如果 telnet文件不存在可以手動創建 添加以下內容
啟動Telnet 查看運行
service xinetd restart ps -ef | grep telnetTelnet客戶端設計
準備工作做好,然后就是根據協議設計Telnet
要更好地理解Telnet數據類型,我們用一個網絡調試助手,直接用TCP連接Telnet服務端,看看返回什么格式,如下圖:
可以看到服務器返回了一段十六進制代碼
然后根據博客
https://www.cnblogs.com/image-eye/archive/2012/03/28/2421726.html
博客中有對應的命令解釋
我們做出如下理解
Telnet連接之后,服務器會與客戶端"協商",例如:
一個Telnet命令由三部分構成,第一個是IAC 固定值為0xFF,表示是一個Telnet,第二部分是命令碼,這里是0xFD,表達的是DO,意為認可選項請求,第三部分為選項碼,這里是18,表示18號功能(查文檔可以知道18號功能對應什么功能)
這句話的意思是,服務器:我想要求18號功能
然后客戶端就要回應,我這里回應的是FF FC 18,意為客戶端拒絕你的請求,拒絕18號功能
其他命令同理。
我們看一段我人為聯系認證的過程
可以看到,在最后的接收數據中,[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服務器
然后就是和服務器協商代碼,我這里為了方便,將服務器的所有請求命令全部拒絕
QByteArray MyTelnet::response(QByteArray data) { //FF FD 18 -> FF FC 18QByteArray 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總結
以上是生活随笔為你收集整理的计算机网络课程设计之TELNET 终端设计与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 树莓派 | threading01 -
- 下一篇: 计算机公共基础知识书第二版答案,二级计算