Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / January 2008

Tip: Looking for answers? Try searching our database.

Custom Telnet Windows Service

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
pbd22 - 14 Jan 2008 17:35 GMT
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();

       }
ssamuel - 14 Jan 2008 18:10 GMT
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 successfully been 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}
pbd22 - 14 Jan 2008 23:16 GMT
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
ssamuel - 14 Jan 2008 23:24 GMT
> Thanks.
>
[quoted text clipped - 3 lines]
>
> 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}
pbd22 - 15 Jan 2008 20:36 GMT
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;

       }

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.