News


*The concepts in this article apply to .NET 1.1 and 3.0 as well, but my links below are for 2.0.

From what I found recently, there are lots of sites that attempt to describe what goes into creating a Telnet session using .NET in general, C# specifically. But not many of them are truly helpful. There are several sites that point you to custom classes, libraries, or even controls that you can download and use blindly. Those leave me feeling like I left the house not wearing any pants.

When you boil down the discussion, it's really just a Socket to some server on port 23, which is the default port for Telnet. So I'm going to try to describe what needs to happen simply and then point you to the site I used to create my own code. I might even post my own code, but it really is mostly a copy-and-paste job from the MSDN site.

A socket is simply a connection to a server. How data gets passed back and forth is just detail info that only the "founding fathers" care about any more. That statement will probably come back and haunt me some day, hopefully not today. Anyway, that's about it. Create a socket on port 23 to a specified server, open it, do your business, and close it.

If you're going to use the System.Net.Sockets class, here's what you do:

  1. Create an IPEndpoint, which points to the specified server and port. You can query DNS.GetHostEntry to change a computer name to an IPHostEntry object.
  2. Create a socket object with the following parameters: AddressFamily.InterNetwork (IP version 4), SocketType.Stream (rides on InterNetwork and Tcp parameters), ProtocolType.Tcp (reliable, two-way connection)
  3. Open the socket like this: socket.Connect(endpoint); //yup, it's that simple
  4. Send your data using socket.Send(... wait, I forgot something. You have to encode the data first so it can fly across them wires.
  5. Use Encoding.ASCII.GetBytes to convert the nice message you have for the server into bytes.
  6. Then use socket.Send to send those bytes on their way.
  7. Listen for a response (one byte at a time, or into a byte array) using socket.Receive
  8. Don't forget to clean up by calling socket.Close()

 

That's all that's really required. There are neat little tricks like asynchronous calls which will allow you to send your data and then pick up the response from the local post office when it's ready (NOT literally, in case you're gullible). Very cool stuff, but I'm trying to present the "quick and dirty, but correct and simple" solution.

Let's look at it another way. You can use a System.Net.Sockets.TcpClient object instead of a socket object, which already has the socket parameters configured to use ProtocolType.Tcp. So let's walk through that option:

  1. Create a new TcpClient object, which takes a server name and a port (no IPEndPoint necessary, nice).
  2. Pull a NetworkStream out of the TcpClient by calling GetStream()
  3. Convert your message into bytes using Encoding.ASCII.GetBytes(string)
  4. Now you can send and receive data using the stream.Write and stream.Read methods, respectively. The stream.Read method returns the number of bytes written to your receiving array, by the way.
  5. Put the data back into human-readable format using Encoding.ASCII.GetString(byte array).
  6. Clean up your mess before the network admins get mad by calling stream.Close() and client.Close().

 

See, wasn't that simple? I knew you could do it. Oh, one little note: If you're trying to log into the machine (first thing, usually), don't forget to send the next-line character "\n" after your user name and password (one each) so that your credentials are submitted. That darn Socket just plan overlooks the fact that it was supposed to hit Enter for you. Incompetent, I know. But be patient, we're all friends here.

If any of you need a challenge to get you through the day, here's one. I was able to connect to one server using this technique but another server passed back a response that appeared to be encoded differently. It had characters like an arrow pointing up and a solid black triangle pointing down. I'm assuming that's Unicode, but I'm unable to read Unicode and I haven't figured out how to get .NET to translate it for me. Yes, I've tried Convert.ToBase64String and Encoding.*.GetString (BigEndian, UTF7, UTF32, etc). Come on now, I hope I'm smarter than that.


posted @ Monday, October 08, 2007 1:43 PM |

Comments

Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Rob on 11/28/2007 3:51 AM
If you want a nice challenge, try doing it asynchronously (connecting and communicating) and create detection when the connection goes dead for whatever reason and then trying to reconnect every x seconds.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Asad Moosa on 6/25/2008 9:18 AM
I understand that you write to explain in words, but i really want a full code. I want a code that connect to telnet in C# and type a command in the text box in Window form to get a response from telnet in the output to Window form. Can you please help me?
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by alankar on 7/16/2008 10:24 AM
when we use stream.write and stream.read we can get telnet responce only once. how can we do it event driven in mean how can i do data arraval event...
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Rob on 7/20/2008 5:55 PM
@Asad My purpose in maintaining a blog is to collaborate and share concepts, not to generate code. If you want to hire me, that can be arranged.

@alankar That is a great question, and another "nice challenge" as I mentioned in a prior comment. Using a socket to listen on some port might work, but that's just my first thought.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by todd on 8/12/2008 9:30 AM
What about handling the telnet protocol negotiation sequence? My understanding was that there's more to it than just opening a socket on port 23, client and server negotiate a set of mutually agreed parameters for the connection...hence your garbage characters.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Rob on 8/12/2008 9:41 AM
@todd
I completely agree- I just don't happen to know the sequence. During the 10 minutes or so that I spent researching, I wasn't able to find any good references on that sequence either.
If you have any recommendations, feel free to post them for general benefit. I've moved on from that project, but it still interests me.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Martl on 9/26/2008 2:53 AM
need to grab the RFC. Goto http://www.faqs.org/rfcs/rfc854.html
you will find the sequence in the specification.

Server and Client do negotiate on supported options, right in the beginning of the connection by passing DO, WILL, DONT, WONT commands. But see the RFC for details.

Best wishes Martin.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Rob on 9/26/2008 7:34 AM
Thanks, Martl. That's exactly what is needed. Good find.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by anon on 2/26/2009 1:15 AM
Well i just cant f##ing believe that microsoft has screwed me again. Even in PHP there are libraries to do this sh1t. go through an RFC no thanks.

Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by learner2009 on 4/1/2009 2:08 AM
Hello Guys, I am beginer and doing some project that involves telnet. first i telnet the targe and then connected. secodly the target is running only in linux also i send come command to execute in thetarget. then there is a result that i would like to display in my VB.net program but i couldn't coz telnet does not use stream so can you guys help me out. thank you


Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Victor on 4/22/2009 9:37 AM
Hi guys,,

Im new in nework programming,I want to connect the unix server from my c# code(windows). Im using tcpclient but I dont know how to pass the username and password from code. Plz help me .thanks in advance


Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Flominator on 6/18/2009 2:55 AM
At first I was annoyed that there was no code, but after I did everything according to your explanation I felt like I really learned something instead of just copying code. Thank you for that!

The only problem I had (that is not so tragic) is that I didn't find a way to find the size of the response or to replace "empty character" from it.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by sudam chavan on 8/22/2009 9:22 AM
suppose i connect to telnet server by using socket object, but can i send commands to telnet sever and get output of that commands
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Personage on 9/15/2009 3:34 PM
It's not telnet just because it's an open socket on port 23. You can use telnet clients to log into web servers, but that doesnt make the web server a telnet server.
Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Richard on 10/8/2009 10:01 AM
Best C# Telnet Lib I've found is called Minimalistic Telnet. Very easy to understand, use and modify. It works great for the Cisco routers I need to configure.

http://www.codeproject.com/KB/IP/MinimalisticTelnet.aspx

Gravatar # re: C# 2.0* and Telnet - Not As Painful As It Sounds
Posted by Telnet-Server Answer on 10/8/2009 12:25 PM
Of course you only get a mess of characters if you just convert the bytes into some kind of format. Each byte has its own meaning in telnet! For more information see: http://support.microsoft.com/kb/231866/en
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: