开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 10437|回复: 4
收起左侧

[分享] 闲得无聊,给大家分享自己写的一段C++版的Telnet协议源码

[复制链接]
结帖率:100% (7/7)
发表于 2015-2-24 22:27:22 | 显示全部楼层 |阅读模式   湖南省益阳市
        首先说明下,因为我是封装成MFC DLL的,所以数据类型代码大多试试MFC的,在这里也不将DLL整个源码发上来了,防止伸手党哈,仅供学习参考。
在写之前,也参考了不少了资料或者源码,不过在百度上找的那些大多都不如意,最后选了一个相对来说写的比较简单的代码用作参考,大家去搜下也知道,大多数都是C#写的类库,但C#写的DLL易语言调用起来要么就是调用不了,要么就是很不方便。测试这个C#写的Telnet类库的时候发现,数据接收并不好使,每次接收数据我看他的代码竟然没做任何判断,是根据数据流里是否有数据来读取的,因为你刚发完数据然后马上调用Receive接收的话,可能对方还没有数据发送过来导致Receive接收失败,按道理来说接收数据写成异步式的比较好,但Telnet完全没有必要,最后下载了一个Telnet的jar包,参考源代码,里面也是没有异步接收,只是很巧妙的根据Telnet的特点每次接收完毕的标志为出现某个字符串时就表示接收完毕了。如在连接上主机的时候,主机会回复一些字符过来,此时肯定最后结尾为login:然后我们以此表示数据接收完毕,因为MFC中的CSocket的Receive是阻塞的,所以肯定要进行判断,否则会一直阻塞在接受状态,然后发送login登录的用户名,会回复Password:,以此类推,登录上后数据结束的标识符就是 #  或者 $ 我们可以根据输入的用户名来区分,root用户为#其他的位$.那个jar包中就是这么实现了。
下面是部分代码(其实差不多就是整个工程了,防止伸手党,所以只给代码了):

  1. <P>const int WILL = 251;
  2. const int WONT = 252;
  3. const int DO = 253;
  4. const int DONT = 254;
  5. const int IAC = 255;
  6. const int RD = 1;
  7. const int SGA = 3;

  8. class CTelnetDLLApp : public CWinApp
  9. {
  10. public:
  11.           CSocket Client;
  12.           const CString LoginPrompt = ":";
  13.           CString prompt;

  14. public:
  15.           CTelnetDLLApp();
  16.           BOOL Connect(char *hostname, int port, char *username, char *password, int waitTime = 300);
  17.           CString Send(CString cmd, int waitTime = 500);
  18.           VOID Close();
  19.           CString ReadUntil(CString pattern);
  20.           CString Negotiate();
  21.           CString RemoveNoString(CString);
  22.          // 重写
  23. public:
  24.            virtual BOOL InitInstance();

  25.            DECLARE_MESSAGE_MAP()
  26. };
  27. </P>
  28. <P> </P>
  29. <P> </P>
  30. <P> </P>
  31. <P> </P>
  32. <P>/**********************************************************************************************/</P>
  33. <P>BOOL CTelnetDLLApp::Connect(char *hostname, int port,char *username,char *password,int waitTime)
  34. {
  35. AfxSocketInit();

  36. if (!Client.Create())
  37. {
  38.   return FALSE;
  39. }</P>
  40. <P> if (Client.Connect((LPCTSTR)hostname, port))
  41. {
  42.   Negotiate();
  43.   CString u(username);
  44.   CString p(password);
  45.   CString result;
  46.   u += "\r\n";
  47.   p += "\r\n";
  48.   prompt = (u == "root\r\n" ? "#" : "$");
  49.   Client.Send(u, u.GetLength());
  50.   result = ReadUntil("Password:");
  51.   //AfxMessageBox(result);
  52.   Client.Send(p, p.GetLength());
  53.   result = ReadUntil(prompt + " ");
  54.   //AfxMessageBox(result);
  55.   if (result.Find("incorrect") > 0 || result.Find("Password") > 0)
  56.   {
  57.    return FALSE;
  58.   }
  59.   return TRUE;
  60. }
  61. return FALSE;
  62. }</P>
  63. <P>CString CTelnetDLLApp::Send(CString cmd, int waitTime)
  64. {
  65. if (cmd == "esc")
  66. {
  67.   byte buff[3];
  68.   buff[0] = 27;
  69.   buff[1] = 10;
  70.   buff[2] = 13;
  71.   Client.Send(buff, 3 * sizeof(byte));
  72.   //Sleep(waitTime);
  73. }
  74. else
  75. {
  76.   cmd += "\r\n";
  77.   Client.Send(cmd, cmd.GetLength());
  78.   //Sleep(waitTime);
  79. }
  80. return ReadUntil(prompt + " ");
  81. }</P>
  82. <P>VOID CTelnetDLLApp::Close()
  83. {
  84. Client.Close();
  85. }</P>
  86. <P>CString CTelnetDLLApp::ReadUntil(CString pattern)
  87. {
  88. char szRecValue[1] = { 0 };
  89. CString res = "";</P>
  90. <P> res = szRecValue;
  91. while (true)
  92. {
  93.   Client.Receive(szRecValue, 1);
  94.   res.AppendChar(szRecValue[0]);
  95.   //AfxMessageBox(res + "|" + pattern);
  96.   if (res.Find(pattern) > 0)
  97.   {
  98.    break;
  99.   }
  100.   memset(szRecValue, 0, 1);
  101. }
  102. res = RemoveNoString(res);
  103. //AfxMessageBox(res);
  104. return res;
  105. }</P>
  106. <P>CString CTelnetDLLApp::Negotiate()
  107. {
  108. CString result;
  109. char szRecValue[1024*4] = { 0 };
  110. while (true)
  111. {
  112.   Client.Receive(szRecValue, 1024 * 4);
  113.   result = szRecValue;
  114.   result.Trim();
  115.   if (result.Right(1) == LoginPrompt)
  116.   {
  117.    break;
  118.   }
  119.   int count = result.GetLength() / 3;
  120.   byte *rev = new byte[result.GetLength()];
  121.   memcpy(rev, result.GetBuffer(result.GetLength()), result.GetLength());
  122.   result.ReleaseBuffer(result.GetLength());
  123.   CString buff = "";
  124.   for (int i = 0; i < count; i++)
  125.   {
  126.    int iac = rev[i * 3];
  127.    int cmd = rev[i * 3 + 1];
  128.    int value = rev[i * 3 + 2];
  129.    if (IAC != iac)
  130.    {
  131.     continue;
  132.    }
  133.    switch (cmd)
  134.    {
  135.    case DO:
  136.     buff += (char)iac;
  137.     buff += (value == RD ? (char)WILL : (char)WONT);
  138.     buff += (char)value;
  139.     Client.Send(buff, buff.GetLength());
  140.     break;
  141.    case DONT:
  142.     buff += (char)iac;
  143.     buff += (char)WONT;
  144.     buff += (char)value;
  145.     Client.Send(buff, buff.GetLength());
  146.     break;
  147.    case WILL:
  148.     buff += (char)iac;
  149.     buff += (value == SGA ? (char)DO : (char)DONT);
  150.     buff += (char)value;
  151.     Client.Send(buff, buff.GetLength());
  152.     break;
  153.    case WONT:
  154.     buff += (char)iac;
  155.     buff += (char)DONT;
  156.     buff += (char)value;
  157.     Client.Send(buff, buff.GetLength());
  158.     break;
  159.    default:
  160.     break;
  161.    }
  162.   }
  163. }
  164. return result;
  165. }</P>
  166. <P>CString CTelnetDLLApp::RemoveNoString(CString buff)
  167. {
  168. CString res = buff;
  169. res.Trim();</P>
  170. <P> int s = res.Find("[32m");
  171. if (s > -1)
  172. {
  173.   do
  174.   {
  175.    res.Delete(s - 1, 5);
  176.    s = res.Find("[32m");
  177.   } while ( s > -1);
  178. }
  179. s = res.Find("[0m");
  180. if (s > -1)
  181. {
  182.   do
  183.   {
  184.    res.Delete(s - 1, 4);
  185.    s = res.Find("[0m");
  186.   } while (s > -1);
  187. }
  188. s = res.Find("[31m");
  189. if (s > -1)
  190. {
  191.   do
  192.   {
  193.    res.Delete(s - 1, 5);
  194.    s = res.Find("[31m");
  195.   } while (s > -1);
  196. }
  197. s = res.Find("[35m");
  198. if (s > -1)
  199. {
  200.   do
  201.   {
  202.    res.Delete(s - 1, 5);
  203.    s = res.Find("[35m");
  204.   } while (s > -1);
  205. }
  206. s = res.Find("[0;0");
  207. if (s > -1)
  208. {
  209.   do
  210.   {
  211.    res.Delete(s - 1, 6);
  212.    s = res.Find("[0;0m");
  213.   } while (s > -1);
  214. }
  215. s = res.Find("[1;34");
  216. if (s > -1)
  217. {
  218.   do
  219.   {
  220.    res.Delete(s - 1, 7);
  221.    s = res.Find("[1;34m");
  222.   } while (s > -1);
  223. }
  224. s = res.Find("[1;36");
  225. if (s > -1)
  226. {
  227.   do
  228.   {
  229.    res.Delete(s - 1, 7);
  230.    s = res.Find("[1;36m");
  231.   } while (s > -1);
  232. }
  233. return res;
  234. }</P>
  235. <P>char * __stdcall execute(char *hostname,
  236. int port,
  237. char *username,
  238. char *password,
  239. char *cmd)
  240. {
  241. CTelnetDLLApp telnet;
  242. if (telnet.Connect(hostname, port, username, password))
  243. {</P>
  244. <P>  CString c(cmd);
  245.   CString result = telnet.Send(c);
  246.   
  247.   LPCTSTR p = result.GetBuffer(result.GetLength() + 1);
  248.   char *res = new char[result.GetLength() + 1];
  249.   strcpy_s(res, result.GetLength() + 1, p);
  250.   result.ReleaseBuffer(result.GetLength() + 1);
  251.   telnet.Close();
  252.   return res;
  253. }
  254. else
  255. {
  256.   telnet.Close();
  257.   return "login failed!";
  258. }
  259. }

  260. </P>
复制代码


发表于 2024-4-21 19:59:25 | 显示全部楼层   山西省太原市
最近在学习,所以在翻历时帖子,谢谢师傅的分享。
回复 支持 反对

使用道具 举报

发表于 2023-1-4 23:19:22 | 显示全部楼层   河南省商丘市
看不懂              
回复 支持 反对

使用道具 举报

结帖率:100% (2/2)

签到天数: 14 天

发表于 2015-5-6 16:08:59 | 显示全部楼层   河南省南阳市
弄成易语言的就好了 这个c的实在看不懂
回复 支持 反对

使用道具 举报

结帖率:42% (30/72)
发表于 2015-2-24 22:34:32 | 显示全部楼层   广东省广州市
支持,看不懂      
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表