我正在开发一个项目,我应该在Unix服务器上运行命令并获得这些命令的完整输出。为此,我使用代码项目(http://www.codeproject.com/Articles/19071/Quick-tool-A-minimalistic-Telnet-library)中的Minimaslistic Telnet库。现在,除了输出之外,一切都很好,因为我想要全部阅读,而不仅仅是它的一部分。我可以拥有可能需要很长时间的命令。这是Minimaslistic Telnet库中的读取输出方法:
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();
}
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;
}
}
}
此代码示例读取输出,但异步,我需要在退出之前等待输出。是否有任何关于更改代码以满足我的要求的想法?谢谢!
答案 0 :(得分:1)
我同意Joachim,在循环中调用read并解析输出结束是最好的方法。对我来说不幸的是,我输出的每个命令都没有标准化结束。相反,我使用流的读取超时来近似输出的结束(我意识到这并不完美)。我设置了更高的初始超时以允许数据开始流动,然后降低超时以找到输出的结束。它看起来像这样:
static string ReadFromStream(int initialTimeout, int subsequentTimeout)
{
// Initialize output
string output = null;
try
{
// Set initial read timeout -- This is needed because occasionally
// it takes a while before data starts flowing
stream.ReadTimeout = initialTimeout;
while (stream.CanRead)
{
// Read bytes in from stream
readBuffer = new byte[tcpClient.ReceiveBufferSize];
stream.Read(readBuffer, 0, tcpClient.ReceiveBufferSize);
// Convert the bytes to string and save to output
output = string.Format("{0}{1}", output, Encoding.ASCII.GetString(readBuffer).Trim());
// Set subsequent read timeout
stream.ReadTimeout = subsequentTimeout;
}
}
// Since we don't know when the output will end, we wait for, and catch the timeout
catch (IOException) { }
// Return output
return output;
}