C# 实现Telnet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace BLL
{
public class TelnetClient
{
private TcpClient Client;
private NetworkStream ns;
private string m_LogonPrompt = "ogin:";
private string m_PasswordPrompt = "assword:";
private readonly int BuffSize = 1024 * 4;
/// <summary>
/// 登录输入用户名提示字符
/// 默认值:ogin:
/// </summary>
public string LoginPrompt
{
set { m_LogonPrompt = value; }
get { return m_LogonPrompt; }
}
/// <summary>
/// 登录输入密码提示字符
/// 默认值:assword:
/// </summary>
public string PasswordPrompt
{
set { m_PasswordPrompt = value; }
get { return m_PasswordPrompt; }
}
/// <summary>
/// 连接状态
/// </summary>
public bool Connected
{
get { return Client != null ? Client.Connected : false; }
}
/// <summary>
/// 连接远端主机
/// </summary>
/// <param name="hostname">主机名称</param>
/// <param name="port">端口</param>
/// <returns>远端主机响应文本</returns>
public string Connect(string hostname, int port)
{
string result = string.Empty;
try
{
Client = new TcpClient(hostname, port);
ns = Client.GetStream();
result = Negotiate();
}
catch (Exception e)
{
result = e.Message;
}
return result;
}
/// <summary>
/// 连接远端主机并登录
/// </summary>
/// <param name="hostname">主机名称</param>
/// <param name="port">端口</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
/// <param name="waitTime">连接等待时间</param>
/// <returns></returns>
public string Connect(string hostname, int port, string username, string password, int waitTime)
{
string result = string.Empty;
result = Connect(hostname, port);
if (Connected && result.EndsWith(LoginPrompt))
{
Send(username, waitTime);
result = Receive();
if (result.EndsWith(PasswordPrompt))
{
Send(password, waitTime);
result = Receive();
if (!result.EndsWith("<"))
{
Client.Close();
result = "Logon Error";
}
}
}
return result;
}
/// <summary>
/// 接收
/// </summary>
/// <returns>传回的数据</returns>
public string Receive()
{
StringBuilder result = new StringBuilder();
if (Connected && ns.CanRead)
{
byte[] buff = new byte[BuffSize];
int numberOfRead = 0;
do
{
numberOfRead = ns.Read(buff, 0, BuffSize);
result.AppendFormat("{0}", Encoding.ASCII.GetString(buff, 0, numberOfRead));
}
while (ns.DataAvailable);
}
return result.ToString().Trim();
}
/// <summary>
/// 发送
/// </summary>
/// <param name="cmd">指令</param>
/// <param name="waitTime">等待超时时间(毫秒)</param>
public void Send(string cmd, int waitTime)
{
if (Connected && ns.CanWrite)
{
cmd += "\r\n";
byte[] buff = Encoding.ASCII.GetBytes(cmd);
ns.Write(buff, 0, buff.Length);
System.Threading.Thread.Sleep(waitTime);
}
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
Client.Close();
}
/// <summary>
/// 处理Telnet选项谈判,直到出现用户名输入提示
/// </summary>
/// <returns></returns>
private string Negotiate()
{
string result = string.Empty;
if (Connected)
{
while (true)
{
byte[] rev = ReceiveBytes();
result = Encoding.ASCII.GetString(rev).Trim();
if (result.EndsWith(LoginPrompt))
{
break;
}
int count = rev.Length / 3;
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 (((int)Verbs.IAC) != iac)
{
continue;
}
switch (cmd)
{
case (int)Verbs.DO:
ns.WriteByte((byte)iac);
ns.WriteByte(value == (int)Options.RD ? (byte)Verbs.WILL : (byte)Verbs.WONT);
ns.WriteByte((byte)value);
break;
case (int)Verbs.DONT:
ns.WriteByte((byte)iac);
ns.WriteByte((byte)Verbs.WONT);
ns.WriteByte((byte)value);
break;
case (int)Verbs.WILL:
ns.WriteByte((byte)iac);
ns.WriteByte(value == (int)Options.SGA ? (byte)Verbs.DO : (byte)Verbs.DONT);
ns.WriteByte((byte)value);
break;
case (int)Verbs.WONT:
ns.WriteByte((byte)iac);
ns.WriteByte((byte)Verbs.DONT);
ns.WriteByte((byte)value);
break;
default:
break;
}
}
}
}
return result;
}
/// <summary>
/// 读取字节流
/// </summary>
/// <returns></returns>
private byte[] ReceiveBytes()
{
byte[] result = new byte[0];
byte[] buff = new byte[BuffSize];
int numberOfRead = 0;
if (Connected && ns.CanRead)
{
numberOfRead = ns.Read(buff, 0, BuffSize);
result = new byte[numberOfRead];
Array.Copy(buff, result, numberOfRead);
} return result;
}
}
enum Verbs
{
WILL = 251,
WONT = 252,
DO = 253,
DONT = 254,
IAC = 255
}
enum Options
{
RD = 1,
SGA = 3
}
}