如果這是一個補救問題,我很抱歉。首先,C#是我學習的第一門編程語言,我已經在過去的一個月裏向自己介紹了基礎知識+。在我的應用程序中,我使用簡約的telnet庫來進行telnet連接並執行命令。問題是我有大約2000個不同的客戶端可以連接,並且大多數是連接到單元。當我用提示快速地向他們telnet一些響應時,在極少數情況下,他們可能需要長達9秒纔會提供登錄提示。簡約telnet提示等待時間
我想要做的就是修改簡約的telnet代碼,等待登錄提示部分長達9秒。
我已經試過到目前爲止正在改變預定義的超時爲9000:
class Telnet
{
TcpClient tcpSocket;
// default timeout 9000
int TimeOutMs = 9000;
我:
string s = tc.Login("root", "pass", 9000);
改變了超時的telnet類的內部,9000和其間的每一組合取代了原來的代碼:
if (prompt != "#" && prompt != "$" && prompt != ":")
throw new Exception("Connection failed");
與我自己的代碼:
while (prompt != "#" && prompt != "$" && prompt != ":" && delay != 19)
{
delay ++
System.Threading.Thread.Sleep(500);
if (delay = 12)
{
updateHistoryWindow(this, "Unit is taking a long time to respond");
}
if (delay = 19)
{
throw new Exception("Connection failed");
updateHistoryWindow(this, "Unit did not display a login prompt");
}
}
使用While命令代替原來的if命令似乎根本不起作用。它不會等待while循環,它的行爲就像它首先超時一樣。
我的應用程序目前分別設置爲2500/2500超時,所有典型的連接都很好。如果我將這些超時值更改爲9000,那麼與典型的18秒相比,連接需要一分鐘或更長時間。我希望儘可能快地保持連接速度,只需等待登錄提示所需的時間,並且在發送命令到服務器之間沒有9秒的延遲。從理論上講,需要5秒鐘的時間才能完成操作的系統需要23秒才能完成操作(其他響應不會像登錄響應那樣延遲)。
- 首先關閉哪個超時會做什麼?是我的Form1中的連接本身和telnet.cs文件中發送命令之間的延遲?
- 我該如何適當延遲登錄提示,但仍然保持過程的其餘部分快速運行。目前,當我更改超時變量時,它會使每個連接永遠持續下去。
- 我可以不使用指定的超時並使用我自己的while循環,我甚至需要這樣做嗎?
- 什麼是Telnet.cs文件與 「oldTimeOutMs」, 「TimeOutMs」 和 「LoginTimeOutMs」 做
下面是我對初始化連接代碼:
try
{
int delay = 0;
Telnet tc = new Telnet(MyGlobals.IP, 23);
//login with user, password, using a timeout of 2500ms, and show server output
string s = tc.Login("root", "pass", 2500);
Console.Write(s);
// Check server output to see if it responds
string prompt = s.TrimEnd();
prompt = s.Substring(prompt.Length - 1, 1);
while (prompt != "#" && prompt != "$" && prompt != ":" && delay != 19)
{
delay ++
System.Threading.Thread.Sleep(500);
if (delay = 12)
{
updateHistoryWindow(this, "Unit is taking a long time to respond");
}
if (delay = 19)
{
throw new Exception("Connection failed");
updateHistoryWindow(this, "Unit did not display a login prompt");
}
}
prompt = "";
// while connected
if (tc.IsConnected)
{ etc....
這裏是大頭來自簡約telnet的telnet.cs供參考:
namespace MYApp
{
enum Verbs
{
WILL = 251,
WONT = 252,
DO = 253,
DONT = 254,
IAC = 255
}
enum Options
{
SGA = 3
}
class Telnet
{
TcpClient tcpSocket;
// default timeout was 2500
int TimeOutMs = 2500;
public Telnet(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);
}
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;
}
}
}
}
}
在此先感謝您的幫助!
我從https://www.nuget.org/packages/Telnet(https://github.com/9swampy上的代碼)獲得了源自minimalistic(已被修改爲按需要工作)的NuGet包/ Telnet /),如果你還沒有排序,可能會有所幫助... – 9swampy