賞金將在 3 天后到期。此問題的答案有資格獲得 50聲望賞金。 Renma正在尋找一個規范的答案:
該解決方案應該有一個很好的解釋,并且適用于這個問題的任何未來讀者。
我有一個 C# WPF 應用程式,它正在建立 Telnet 連接以將一些內容從 Windows 系統寫入 Linux 系統上的檔案。所以說我有一些這樣的文字。
這是一個位\tof text \r\n 后跟一個新行。
以下是代碼的一般情況:
string ipAddress = "11.11.11.11";
int port = 66;
TelnetConnection tc = new TelnetConnection(ipAddress, port);
string s = tc.Login("root", "password", 100);
string prompt = s.TrimEnd();
if (prompt != "$" && prompt != "#"){
throw new Exception("Connection failed");
}
tc.WriteLine("echo $'Here is a bit\tof text \r\n Followed by a new line.' >> MyFile.txt");
這是我使用的 TelnetConnection 類:\
enum Verbs
{
WILL = 251,
WONT = 252,
DO = 253,
DONT = 254,
IAC = 255
}
enum Options
{
SGA = 3
}
class TelnetConnection
{
TcpClient tcpSocket;
int TimeOutMs = 10;
public TelnetConnection(string Hostname, int Port)
{
tcpSocket = new TcpClient(Hostname, Port);
}
public string Login(string Username, string Password, int LoginTimeOutMs)
{
int oldTimeOutMs = TimeOutMs;
TimeOutMs = LoginTimeOutMs;
string s = Read();
if (!s.TrimEnd().EndsWith(":"))
throw new Exception("Failed to connect : no login prompt");
WriteLine(Username);
s = Read();
if (!s.TrimEnd().EndsWith(":"))
throw new Exception("Failed to connect : no password prompt");
WriteLine(Password);
s = Read();
TimeOutMs = oldTimeOutMs;
return s;
}
public void WriteLine(string cmd)
{
Write(cmd "\n");
}
public void Write(string cmd)
{
if (!tcpSocket.Connected) return;
byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));
tcpSocket.GetStream().Write(buf, 0, buf.Length);
System.Threading.Thread.Sleep(1000);
}
public string Read()
{
if (!tcpSocket.Connected) return null;
StringBuilder sb = new StringBuilder();
do
{
ParseTelnet(sb);
System.Threading.Thread.Sleep(TimeOutMs);
} while (tcpSocket.Available > 0);
return sb.ToString();
}
public bool IsConnected
{
get { return tcpSocket.Connected; }
}
void ParseTelnet(StringBuilder sb)
{
while (tcpSocket.Available > 0)
{
int input = tcpSocket.GetStream().ReadByte();
switch (input)
{
case -1:
break;
case (int)Verbs.IAC:
// interpret as command
int inputverb = tcpSocket.GetStream().ReadByte();
if (inputverb == -1) break;
switch (inputverb)
{
case (int)Verbs.IAC:
//literal IAC = 255 escaped, so append char 255 to string
sb.Append(inputverb);
break;
case (int)Verbs.DO:
case (int)Verbs.DONT:
case (int)Verbs.WILL:
case (int)Verbs.WONT:
// reply to all commands with "WONT", unless it is SGA (suppres go ahead)
int inputoption = tcpSocket.GetStream().ReadByte();
if (inputoption == -1) break;
tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
if (inputoption == (int)Options.SGA)
tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL : (byte)Verbs.DO);
else
tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
tcpSocket.GetStream().WriteByte((byte)inputoption);
break;
default:
break;
}
break;
default:
sb.Append((char)input);
break;
}
}
}
}
當我去檢查檔案時,它是這樣寫入的
這是一段文本
,后跟一個新行。
所以制表符甚至沒有被讀取,但新行是出于某種原因。有任何想法嗎?
uj5u.com熱心網友回復:
這實際上非常簡單,并且不是特定于 telnet 的。
打開 Powershell 或 Cmd 并嘗試輸入您的字串,您將看到。
命令列將 tab 解釋為命令完成(自動完成最接近的匹配 ex. '>ec\t' 將產生 '>echo'),移動到下一個欄位或丟棄 tab。
您需要用空格替換 '\t' (用于此特定用途)。
標簽通常可以通過 telnet 發送。我一直都這樣做。通常,服務器將其解釋為移動到下一個欄位的請求。
例如 'MyName\tpassword' 將用 MyName 填寫第一個欄位,然后移動到下一個欄位并填寫密碼
uj5u.com熱心網友回復:
這取決于您連接到的系統以及在那里運行的 shell,但您可能需要使用雙轉義選項卡,這樣不僅\t可以\\t將 a\和 at發送到 shell。但是隨后您需要啟用 echo 命令以將其解釋為不是字串,而是通過bash 中\t的開關完成的轉義。-e至少在 bash 中應該是這樣的。
tc.WriteLine("echo -e \"Here is a bit\\tof text \\r\\n Followed by a new line.\" >> MyFile.txt");
uj5u.com熱心網友回復:
使用printf更可預測
tc.WriteLine("printf 'Here is a bit\tof text \r\n Followed by a new line.\n' >> MyFile.txt");
你也可以使用xxd(或類似的)來驗證內容
printf 'Here is a bit\tof text \r\n Followed by a new line.\n' | xxd
00000000: 4865 7265 2069 7320 6120 6269 7409 6f66 Here is a bit.of
00000010: 2074 6578 7420 0d0a 2046 6f6c 6c6f 7765 text .. Followe
00000020: 6420 6279 2061 206e 6577 206c 696e 652e d by a new line.
00000030: 0a .
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/461195.html
上一篇:pthread_cond_wait永遠不會回傳EOWNERDEAD
下一篇:腳本不適用于高性能計算機
