Custom Telnet Windows Service

P

pbd22

Hi

I am making my way through a windows service that accepts
custom telnet commands as strings and then parses the string
and redirects it.

This would be a custom string sent via telnet.

So, I need to prompt the user for input and then capture
that imput, parse it into a form that is readable (strings in
variables) and then send it somewhere (to a database or
xml).

What I have right now hijacks the telnet connection by
spawning a tread and queuing connections, but I am
still unclear how to send custom prompts to the user
and capture responses.

Also, I need a login (username/password) before we can
start.

Below is my code. Could somebody walk me through
how to add the interactivity?

Much appreciated!


protected override void OnStart(string[] args)
{
this.timer1.Enabled = true;
new Thread(new ThreadStart(Listen)).Start();
}

/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
this.timer1.Enabled = false;
this.Listen(); // stop / start
}

private void timer1_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
this.Listen();
}

public void Listen()
{

eventLog2.WriteEntry("Listener Service Started...",
EventLogEntryType.Information);

try
{
Queue unsyncq = new Queue();
connectionQueue = Queue.Synchronized(unsyncq);
}
catch( Exception e)
{
eventLog2.WriteEntry( "Error in Listener method ( queue
related ) : " + e.Message, EventLogEntryType.Error);
return;
}

try
{

TcpClient socket;
TcpListener listener = new TcpListener(IPAddress.Any,
23);

listener.Start();

while( true)
{
socket = listener.AcceptTcpClient();
connectionQueue.Enqueue(socket);

Thread workingthread = new Thread(new
ThreadStart(TheConnectionHandler));
workingthread.Start(socket);


}

}
catch( Exception e)
{
eventLog2.WriteEntry( "Error in Listener method
( connection related ) :" + e.Message, EventLogEntryType.Error);
return;
}

}

public void TheConnectionHandler()
{

TcpClient socket =
(TcpClient)connectionQueue.Dequeue();

byte[] message = new byte[4096];
int bytesRead;

while (true)
{

bytesRead = 0;

try
{


//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0,
4096);

}
catch
{
//a socket error has occured
break;
}

if (bytesRead == 0)
{

//the client has disconnected from the server
break;

}

//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
System.Diagnostics.Debug.WriteLine(
encoder.GetString(message, 0, bytesRead));

}

socket.Close();

}
 
S

ssamuel

Hi.

I'm assuming everything's worked until now and you're getting what the
user types on the server side dumped to the destination of your Debug.
Here's where you need to do something:
                        //message has successfullybeen received
                        ASCIIEncoding encoder = new ASCIIEncoding();
                        System.Diagnostics.Debug.WriteLine(
                        encoder.GetString(message,0, bytesRead));

You have a string -- encoder.GetString() gives you one -- so parse it
then return the proper response. You may try something like this:

protected string Response(string input)
{
if (input == "hello")
return "hello, back.";
}

Then you need to take the contents of the string you get back and push
it back into your stream. clientStream.Write() is a good place to
look.

If you want to do prompts, you should push out a prompt as soon as you
make the connection, before first listening for a response. Some
servers expect some input before the first prompt (many telnet
implementations expect a CR from the client before they provide the
first prompt). Then prompt wish "Username: " and read the response.
When the user this enter (you get a CR character), prompt "Password: "
and read the response. Check the username and password provided
against your lookup. If it's invalid, go back to the start. If it's
valid, provide the first 'do something' prompt.

HTH!

s}
 
P

pbd22

Thanks.

Do I pass "encoder" as an argument to Response?
If this is wrong, would you mind providing a bit more code to give me
a better understanding?

Thanks
 
S

ssamuel

Thanks.

Do I pass "encoder" as an argument to Response?
If this is wrong, would you mind providing a bit more code to give me
a better understanding?

Thanks

No, you pass the output of encoder.GetString(). When you get data from
the TCP/IP stream, you're assuming they're ASCII-encoded bytes. In any
case, they're bytes, not string data, so you need to convert them into
something that'll fit in a string. That's what encoder.GetString()
does for you.

The Response method would take a string argument, so you need to pass
it the output of the encoder.

s}
 
P

pbd22

OK, thanks.
Another question...

Why is it that I have to hit CR twice to get the response sent to the
term?

this is in a while loop ( while(true) )

statusMessage += ASCII.GetString(message, 0, _bytesRead);

if (statusMessage.LastIndexOf("\r\n") > 0)
{

buffer =
ASCII.GetBytes(ReadResponse(statusMessage));

_clientStream.Write(buffer, 0, buffer.Length);
_clientStream.Flush();

statusMessage = "";

}



and, outside the method for the above code....

protected string ReadResponse(string clientInput)
{
if (clientInput == "hello\r\n")
return "hello, back.";
else
return String.Empty;

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top