最近遇到一個業(yè)務(wù)需求:客戶端自動登錄遠(yuǎn)程Telnet服務(wù)器,然后自動發(fā)出一系列指令,返回指令執(zhí)行結(jié)果。
這里,我采用 TcpClient 來與遠(yuǎn)程服務(wù)器Telnet服務(wù)通信(默認(rèn)端口:23)。這方面,網(wǎng)絡(luò)上有不少的代碼與文章。
完成之后,因需求變更,遇到了一個新的問題,就是客戶機器需要通過 HTTP 代理來連接公網(wǎng)的 Telnetb 服務(wù)器。在這種情況,TcpClien 連接需要經(jīng)過 HTTP 代理來與服務(wù)器通信。這方面代碼幾番求助度娘、谷歌無果。沒辦法,自己分析 HTTP 代理。
代理過程:
(1)客戶機連接代理服務(wù)器;
(2)代理服務(wù)器請求連接Telnet服務(wù)器,Telnet服務(wù)器返回響應(yīng);
(3)代理服務(wù)器將Telnet返回響應(yīng)傳給客戶端。
HTTP/1.0協(xié)議支持的請求方法有:GET、POST、PUT、DELETE、CONNECT等。同樣HTTP代理服務(wù)器也這些請求方法。如:使用 GET/POST 方法代理訪問網(wǎng)頁等。
現(xiàn)在,要用的是 CONNECT 請求方法,去連接 Telnet 服務(wù)器。如下:
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服務(wù)IP與端口。
接下來,就是利用HTTP代理,創(chuàng)建一個連接到Telnet服務(wù)器的 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); // 連接代理服務(wù)器.
// CONNECT Telnet 服務(wù)器
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 服務(wù)通信成功。