Telnet Client

0 votes
asked Nov 25, 2013 by amoreck (150 points)
edited Nov 27, 2013
        Telnet client = new Telnet("192.168.1.10", 7001);
        tcConsole.Bind(client);

        Shell shell = client.StartShell();
        shell.SendCommand("");
        shell.ReadAll("?");

When i connect to the above IP address and port the host should delay about 2 seconds then give a prompt

"Entering server port, ..... type ^z for port menu."

At this point i want the shell to send a return character to get my next prompt

"Router>"

i always get "Cannot send command while running." exception when sending a command to the shell.

Please help

3 Answers

0 votes
answered Nov 26, 2013 by Lukas Matyska (47,150 points)
edited Nov 26, 2013
 
Best answer

You have to read initial welcome message first, to be able to send a command. Also, you have to set the Prompt property first. It can be done like this:

Telnet client = new Telnet("192.168.1.10", 7001);
Shell shell = client.StartShell();

// set expected prompt
shell.Prompt = "Router>";

// read initial welcome message ended with "port menu."
shell.ReadAll("port menu.");

// send a return character
shell.SendCommand("");

// read response up to the prompt ("Router>" in this case) or 
// alternate prompt ("?" in this case)
shell.ReadAll("?");

Please note that spaces are taken in effect. It means, that your prompt can be rather "Router> " and/or alternate prompt can be "? " instead. Of course, it depends on the particular server responses.

Also please note that tcConsole.Bind(client) and client.StartShell() creates two separate connections. It means that actions done on shell have no effect to the tcConsole and vice versa.

commented Nov 26, 2013 by amoreck (150 points)
edited Nov 26, 2013

How can i "watch" the session as my program communicates with the server. Logging to a text file would be fine.

commented Nov 26, 2013 by amoreck (150 points)
edited Nov 26, 2013

the ReadAll("?") does not seem to work. ReadAll(">") does work

My next prompt may be ANYTHING it would end in a ">" or "#" text before that is variable.

0 votes
answered Nov 27, 2013 by Pavel Matyska (10,800 points)
edited Nov 27, 2013

For the recording task please follow the tutorial article which can be found here: recording tutorial article. After the log is created you can actually "see" the communication. Just use one of our sample application named AnsiPlayer. If you don't have it, you can dowload it here: AnsiPlayer sample application

For the ReadAll("?"): the parameter of the method is alternative expected prompt. It is used in cases when the server need additional info for the command currently executing. E.g. you send command to delete a file, and the server need confirmation. It is not ment to use with regular prompt as "user@device>" and so on.

If the regular prompt varies (e.g with current directory on the server), you can specify the prompt as regular expression. In your case it could be

shell.Prompt = "regex:^[^>#]*[>#]";

(you can learn more about regular expressions on MSDN regular expression page ). As you know from before spaces are taken in effect.

0 votes
answered Nov 27, 2013 by Lukas Matyska (47,150 points)
edited Nov 27, 2013

Actually, my colleague missed that you are using Shell class, but the Recorder is available only with VirtualTerminal or TerminalControl classes.

When using Shell class, you have to use other kind of approach:

  1. use Telnet.LogWriter property with FileLogWriter in Verbose mode
  2. use Telnet.LogWriter property with modified FileLogWriter class
  3. write wrapper around Shell class and log sent and received data manually

Sample usage of 1. (very verbose)

client.LogWriter = new FileLogWriter(@"path", LogLevel.Verbose);

Sample usage of 2. (logs only sent and received data in text form)

public class MyFileLogWriter : FileLogWriter
{
    public MyFileLogWriter(string path) : base(path, LogLevel.Verbose) { }

    public override void Write(LogLevel level, Type objectType, int objectId, string area, string message)
    {
    }

    public override void Write(LogLevel level, Type objectType, int objectId, string area, string message, byte[] buffer, int offset, int length)
    {
        if ((level < Level) || (level == LogLevel.Off))
            return;

        WriteMessage(string.Format("{0}\r\n{1}\r\n", message, Encoding.UTF8.GetString(buffer, offset, length)));
    }
}


client.LogWriter = new MyFileLogWriter(@"path");

Sample usage of 3.

public class ShellWrapper
{
    Shell _inner;

    public ShellWrapper(Shell shell)
    {
        _inner = shell;
    }

    private string LogReceivedData(string data)
    {
        Console.WriteLine("Received data:");
        Console.WriteLine(data);
        return data;
    }

    private char LogReceivedData(char data)
    {
        Console.WriteLine("Received data:");
        Console.WriteLine(data);
        return data;
    }

    private string LogSentData(string data)
    {
        Console.WriteLine("Sent data:");
        Console.WriteLine(data);
        return data;
    }

    public bool Connected { get { return _inner.Connected; } }
    public Encoding Encoding { get { return _inner.Encoding; } set { _inner.Encoding = value; } }
    public bool IsRunning { get { return _inner.IsRunning; } }
    public string LastMatchedPrompt { get { return _inner.LastMatchedPrompt; } }
    public ShellMode Mode { get { return _inner.Mode; } }
    public string Prompt { get { return _inner.Prompt; } set { _inner.Prompt = value; } }
    public bool StripEscapeSequences { get { return _inner.StripEscapeSequences; } set { _inner.StripEscapeSequences = value; } }
    public int Timeout { get { return _inner.Timeout; } set { _inner.Timeout = value; } }

    public void Close() { _inner.Close(); }
    public int GetExitCode() { return _inner.GetExitCode(); }

    public string ReadAll() { return LogReceivedData(_inner.ReadAll()); }
    public string ReadAll(params string[] questionPrompt) { return LogReceivedData(_inner.ReadAll(questionPrompt)); }
    public char ReadChar() { return LogReceivedData(_inner.ReadChar()); }
    public string ReadLine() { return LogReceivedData(_inner.ReadLine()); }
    public string ReadLine(params string[] questionPrompt) { return LogReceivedData(_inner.ReadLine(questionPrompt)); }

    public void SendBreak(int breakLength) { LogSentData("<BREAK>"); _inner.SendBreak(breakLength); }
    public void SendCommand(string command) { LogSentData(command); _inner.SendCommand(command); }
    public void SendCommand(string command, bool password) { LogSentData(command); _inner.SendCommand(command, password); }
}

var shell = new ShellWrapper(client.StartShell());
...