最近遇到一個業務需求:客戶端自動登錄遠程Telnet服務器,然后自動發出一系列指令,返回指令執行結果。
這里,我采用 TcpClient 來與遠程服務器Telnet服務通信(默認端口:23)。這方面,網絡上有不少的代碼與文章。
完成之后,因需求變更,遇到了一個新的問題,就是客戶機器需要通過 HTTP 代理來連接公網的 Telnetb 服務器。在這種情況,TcpClien 連接需要經過 HTTP 代理來與服務器通信。這方面代碼幾番求助度娘、谷歌無果。沒辦法,自己分析 HTTP 代理。
代理過程:
(1)客戶機連接代理服務器;
(2)代理服務器請求連接Telnet服務器,Telnet服務器返回響應;
(3)代理服務器將Telnet返回響應傳給客戶端。
HTTP/1.0協議支持的請求方法有:GET、POST、PUT、DELETE、CONNECT等。同樣HTTP代理服務器也這些請求方法。如:使用 GET/POST 方法代理訪問網頁等。
現在,要用的是 CONNECT 請求方法,去連接 Telnet 服務器。如下:
CONNECT xxx.xxx.xxx.xxx:23 HTTP/1.0
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)
xxx.xxx.xxx.xxx:23,為Telnet服務IP與端口。
接下來,就是利用HTTP代理,創建一個連接到Telnet服務器的 TcpCient 實例對象。
public TcpClient CreateTcpClient(string proxyHost, int proxyPort, string telnetHost, int telnetPort)
{
IPHostEntry entry = Dns.GetHostEntry(proxyHost);
IPEndPoint ipEndPoint = new IPEndPoint(entry.AddressList[0], proxyPort);
TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork);
tcpClient.Connect(ipEndPoint); // 連接代理服務器.
// CONNECT Telnet 服務器
string connectCommand = string.Format("CONNECT {0}:{1} HTTP/1.0\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)\n\n", telnetHost, telnetPort);
byte[] buffer = Encoding.ASCII.GetBytes(connectCommand);
tcpClient.GetStream().Write(buffer, 0, buffer.Length);
buffer = new byte[512];
int received = tcpClient.GetStream().Read(buffer, 0, 512);
string receivedText = Encoding.ASCII.GetString(buffer, 0, received);
// 成功.
if (receivedText.IndexOf("200") > -1)
return tcpClient;
return null;
}
這樣的 TcpClient 通過代理與 Telnet 服務通信成功。