|
首先说明下,因为我是封装成MFC DLL的,所以数据类型代码大多试试MFC的,在这里也不将DLL整个源码发上来了,防止伸手党哈,仅供学习参考。
在写之前,也参考了不少了资料或者源码,不过在百度上找的那些大多都不如意,最后选了一个相对来说写的比较简单的代码用作参考,大家去搜下也知道,大多数都是C#写的类库,但C#写的DLL易语言调用起来要么就是调用不了,要么就是很不方便。测试这个C#写的Telnet类库的时候发现,数据接收并不好使,每次接收数据我看他的代码竟然没做任何判断,是根据数据流里是否有数据来读取的,因为你刚发完数据然后马上调用Receive接收的话,可能对方还没有数据发送过来导致Receive接收失败,按道理来说接收数据写成异步式的比较好,但Telnet完全没有必要,最后下载了一个Telnet的jar包,参考源代码,里面也是没有异步接收,只是很巧妙的根据Telnet的特点每次接收完毕的标志为出现某个字符串时就表示接收完毕了。如在连接上主机的时候,主机会回复一些字符过来,此时肯定最后结尾为login:然后我们以此表示数据接收完毕,因为MFC中的CSocket的Receive是阻塞的,所以肯定要进行判断,否则会一直阻塞在接受状态,然后发送login登录的用户名,会回复Password:,以此类推,登录上后数据结束的标识符就是 # 或者 $ 我们可以根据输入的用户名来区分,root用户为#其他的位$.那个jar包中就是这么实现了。
下面是部分代码(其实差不多就是整个工程了,防止伸手党,所以只给代码了):
- <P>const int WILL = 251;
- const int WONT = 252;
- const int DO = 253;
- const int DONT = 254;
- const int IAC = 255;
- const int RD = 1;
- const int SGA = 3;
- class CTelnetDLLApp : public CWinApp
- {
- public:
- CSocket Client;
- const CString LoginPrompt = ":";
- CString prompt;
- public:
- CTelnetDLLApp();
- BOOL Connect(char *hostname, int port, char *username, char *password, int waitTime = 300);
- CString Send(CString cmd, int waitTime = 500);
- VOID Close();
- CString ReadUntil(CString pattern);
- CString Negotiate();
- CString RemoveNoString(CString);
- // 重写
- public:
- virtual BOOL InitInstance();
- DECLARE_MESSAGE_MAP()
- };
- </P>
- <P> </P>
- <P> </P>
- <P> </P>
- <P> </P>
- <P>/**********************************************************************************************/</P>
- <P>BOOL CTelnetDLLApp::Connect(char *hostname, int port,char *username,char *password,int waitTime)
- {
- AfxSocketInit();
-
- if (!Client.Create())
- {
- return FALSE;
- }</P>
- <P> if (Client.Connect((LPCTSTR)hostname, port))
- {
- Negotiate();
- CString u(username);
- CString p(password);
- CString result;
- u += "\r\n";
- p += "\r\n";
- prompt = (u == "root\r\n" ? "#" : "$");
- Client.Send(u, u.GetLength());
- result = ReadUntil("Password:");
- //AfxMessageBox(result);
- Client.Send(p, p.GetLength());
- result = ReadUntil(prompt + " ");
- //AfxMessageBox(result);
- if (result.Find("incorrect") > 0 || result.Find("Password") > 0)
- {
- return FALSE;
- }
- return TRUE;
- }
- return FALSE;
- }</P>
- <P>CString CTelnetDLLApp::Send(CString cmd, int waitTime)
- {
- if (cmd == "esc")
- {
- byte buff[3];
- buff[0] = 27;
- buff[1] = 10;
- buff[2] = 13;
- Client.Send(buff, 3 * sizeof(byte));
- //Sleep(waitTime);
- }
- else
- {
- cmd += "\r\n";
- Client.Send(cmd, cmd.GetLength());
- //Sleep(waitTime);
- }
- return ReadUntil(prompt + " ");
- }</P>
- <P>VOID CTelnetDLLApp::Close()
- {
- Client.Close();
- }</P>
- <P>CString CTelnetDLLApp::ReadUntil(CString pattern)
- {
- char szRecValue[1] = { 0 };
- CString res = "";</P>
- <P> res = szRecValue;
- while (true)
- {
- Client.Receive(szRecValue, 1);
- res.AppendChar(szRecValue[0]);
- //AfxMessageBox(res + "|" + pattern);
- if (res.Find(pattern) > 0)
- {
- break;
- }
- memset(szRecValue, 0, 1);
- }
- res = RemoveNoString(res);
- //AfxMessageBox(res);
- return res;
- }</P>
- <P>CString CTelnetDLLApp::Negotiate()
- {
- CString result;
- char szRecValue[1024*4] = { 0 };
- while (true)
- {
- Client.Receive(szRecValue, 1024 * 4);
- result = szRecValue;
- result.Trim();
- if (result.Right(1) == LoginPrompt)
- {
- break;
- }
- int count = result.GetLength() / 3;
- byte *rev = new byte[result.GetLength()];
- memcpy(rev, result.GetBuffer(result.GetLength()), result.GetLength());
- result.ReleaseBuffer(result.GetLength());
- CString buff = "";
- for (int i = 0; i < count; i++)
- {
- int iac = rev[i * 3];
- int cmd = rev[i * 3 + 1];
- int value = rev[i * 3 + 2];
- if (IAC != iac)
- {
- continue;
- }
- switch (cmd)
- {
- case DO:
- buff += (char)iac;
- buff += (value == RD ? (char)WILL : (char)WONT);
- buff += (char)value;
- Client.Send(buff, buff.GetLength());
- break;
- case DONT:
- buff += (char)iac;
- buff += (char)WONT;
- buff += (char)value;
- Client.Send(buff, buff.GetLength());
- break;
- case WILL:
- buff += (char)iac;
- buff += (value == SGA ? (char)DO : (char)DONT);
- buff += (char)value;
- Client.Send(buff, buff.GetLength());
- break;
- case WONT:
- buff += (char)iac;
- buff += (char)DONT;
- buff += (char)value;
- Client.Send(buff, buff.GetLength());
- break;
- default:
- break;
- }
- }
- }
- return result;
- }</P>
- <P>CString CTelnetDLLApp::RemoveNoString(CString buff)
- {
- CString res = buff;
- res.Trim();</P>
- <P> int s = res.Find("[32m");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 5);
- s = res.Find("[32m");
- } while ( s > -1);
- }
- s = res.Find("[0m");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 4);
- s = res.Find("[0m");
- } while (s > -1);
- }
- s = res.Find("[31m");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 5);
- s = res.Find("[31m");
- } while (s > -1);
- }
- s = res.Find("[35m");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 5);
- s = res.Find("[35m");
- } while (s > -1);
- }
- s = res.Find("[0;0");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 6);
- s = res.Find("[0;0m");
- } while (s > -1);
- }
- s = res.Find("[1;34");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 7);
- s = res.Find("[1;34m");
- } while (s > -1);
- }
- s = res.Find("[1;36");
- if (s > -1)
- {
- do
- {
- res.Delete(s - 1, 7);
- s = res.Find("[1;36m");
- } while (s > -1);
- }
- return res;
- }</P>
- <P>char * __stdcall execute(char *hostname,
- int port,
- char *username,
- char *password,
- char *cmd)
- {
- CTelnetDLLApp telnet;
- if (telnet.Connect(hostname, port, username, password))
- {</P>
- <P> CString c(cmd);
- CString result = telnet.Send(c);
-
- LPCTSTR p = result.GetBuffer(result.GetLength() + 1);
- char *res = new char[result.GetLength() + 1];
- strcpy_s(res, result.GetLength() + 1, p);
- result.ReleaseBuffer(result.GetLength() + 1);
- telnet.Close();
- return res;
- }
- else
- {
- telnet.Close();
- return "login failed!";
- }
- }
- </P>
复制代码
|
|