Telnet

[ LiB ]

Way back in the bad old days before the Internet even existed, all computer-human interaction was done on something called a terminal . Essentially, a terminal is just a screen that prints characters as a display and is connected to a keyboard on which the user types the characters . Terminals are usually connected to a mainframe or a server via a phone line or some other means.

When the Internet came along, it was possible to connect computers over TCP/IP, but there was no standard way of emulating the relationship between a terminal and a server. Then along came Telnet. The latest Telnet protocol is defined in RFC 854, and it's not likely to change.

Essentially, the Telnet protocol says that a stream of 7-bit characters is going to be transmitted in duplex mode (both ways); this stream of characters can contain occasional control codes that define the behavior of the terminal device.

You won't be concerned with the majority of the control codes available, so I won't explain them in depth.

Simple Telnet Example

I want to show you a simple example of a Telnet server. This server simply accepts characters that are sent to it, buffers them, and then prints them back out to the terminal when an end of line is reached. In Telnet, the end of a line is always signaled with a carriage -return, line-feed combination, also known as CRLF. A CRLF in C++ is represented by the escape codes "\r\n" .

At this point, I want to begin Demo 6.1, which can be found on the CD in the \Demos\Chapter06\Demo06-01\ directory. It uses the SocketLib, and you can find compilation instructions for the demo in Appendix A, which is on the CD.

NOTE

If you're running either VC6 or VC7, you can just open up the project files and click Compile, assuming you've set up your compiler as specified in Appendix A , " Setting Up Your Compilers, " which is on the CD. In Linux, all you need to do is type "make" and the demo compiles.

Demo 6.1Very Simple Telnet Server
 #include "SocketLib/SocketLib.h" using namespace SocketLib; int main() {     ListeningSocket lsock;     DataSocket dsock;     char buffer[128];     int size = 0;     int received;     lsock.Listen( 5098 );      // listen on port 5098     dsock = lsock.Accept();    // wait for a connection 

The previous code sets up two sockets (one listening, one data), a buffer, and two integers. The listening socket is told to listen on port 5098. Then the listening socket is told to wait for a data connection using the Accept function.

 dsock.Send( "Hello!\r\n", 8 );   // send "Hello!" to client when connected     while( true ) {                  // run for eternity         received = dsock.Receive( buffer + size, 128 - size );         size += received;         if( buffer[size - 1] == '\n' ) {      // when you get an "\n",             std::cout << size << std::endl;   // print size of string             dsock.Send( buffer, size );       // send it back to client             size = 0;                         // reset the size         }     }     return 0; } 

The last code segment first sends a welcome message"Hello!"and then it loops infinitely, trying to receive data from the data socket. Whenever data is received, the size is updated, and the last character is checked to see if it is '\n' , a linefeed character. If so, the buffer is sent out, and the size is reset. That's it.

NOTE

The default Telnet port is 23, but Linux does not allow you to open ports below 1024 unless you are root. Because of this, I've chosen to run on an arbitrary port.

Here are a few caveats about the program. If you reach 128 characters without pressing Enter, the server crashes, since it's trying to receive 0 bytes (128 - 128 = 0), and that's not allowed by the Socket Library. (Think about it; why would you try to receieve 0 bytes?) The server must receive at least 1 byte. So don't type more than 128 characters. This process is illustrated in Figure 6.1.

Figure 6.1. One string of text, "Hello computer" being received from a client. At the start, a full buffer of 128 bytes can be received, but after receiving "Hello computer", the size becomes 14, and only 114 more bytes can be received before the buffer is full.

graphic/06fig01.gif


Also, when the client is closed, the server automatically terminates, because an exception is thrown whenever the server tries to receive data from the socket after it has been closed. This program does not catch it, and allows the exception to propogate upward until the program terminates. This is a little messy, but you get the idea. Eventually, you'll see more robust programs, instead of this little hack.

Running Demo 6.1

After you've compiled the program, you can run it on the operating system you compiled it for. Once the server is running, you can connect to it using your favorite Telnet program. Windows and Linux have Telnet programs built in, so you can open a Telnet program simply by typing "Telnet localhost 5098" on a command line, or by replacing 'localhost' with the address of the machine you're running it on, if it's not the same machine. There are other popular Telnet clients out there as well; the most popular is probably PuTTY. (TTY is an acronym that typically stands for TeleTYpewriter. ) You can find the newest version at http://www.chiark.greenend.org.uk/~sgtatham/putty/, but I've also included a version on the CD in the directory / goodies / Clients/PuTTY/. (It even comes with source code, if you're devious enough to want to see it.)

Once you're connected, you can type various strings of text. Try typing "testing". The string "testing" is printed out while you're typing it. (Systems may vary.) Then you can press Enter, and "testing" should appear on the next line as well. If you look at the console window on which the server is running, it should have printed out the number "9", which means that it received 9 characters: the 7 characters in "testing", and the CRLF 2-character combination representing the end of the line.

NOTE

PuTTY is a really great Telnet pro gram that wonderfully supports all Telnet options (I will explain these to you a little bit later), unlike certain other Telnet programs out there. However, because the servers in this book won't support Telnet options, you can simply set PuTTY to "raw" mode. It will still interpret VT100 codes, but it won't process or send Telnet option packets.

Processing Codes

The Telnet standard uses 7-bit ASCII as its method of data transmission. 7-bit ASCII actually takes up 8 bits of space; it defines the first 128 values in each byte and leaves the last bit undefined. There is an 8-bit ASCII format as well, which puts the total number of defined characters at 256. But Telnet doesn't officially support them, and there's no guarantee that any Telnet clients or servers will be able to support characters with codes larger than 127.

If you look at the values of the first 32 ASCII characters, you can see that they are not actual characters, but are control codes. Here are the most common ones:

10 means "newline"

13 means "carriage-return"

8 means " backspace "

9 means "tab"

7 means "bell"

NOTE

Way back in the bad-old days, before there were even computer monitors , computer output was displayed on mechanical typewriters. These type writers understood ASCII codes and used them to format output. For example, the "carriage return" code told the printer head on the type writer to move all the way back to the left, and the "newline" code would move the paper up one line. The "bell" code would make a little bell on the printer ring. Incidentally, many Telnet programs still support the bell code, and you can use it annoy people.

Most of the other codes are no longer used, so they aren't that important.

So, when a Telnet server or client is receiving characters, it needs to actually process the meanings of some of these codes.

Load up Demo 6.1 again. This time, type in "aaabbbccc", and press Enter. The server should say it received 11 characters. Now, type "aaabbbccc", and then press Backspace three times. Then type "ddd" and press Enter. What is printed? It's "aaabbbddd". But, how many characters did the server get and then send out again? It should now say 17, even though 11 characters are printed to the Telnet client (9 letters , 1 CR, 1 LF). The truth is that you sent "aaabbbccc<backspace><backspace><backspace>ddd<CR><LF>" back to the client. The client erased those three c's when it found the backspace codes and replaced them with the d's.

So, both sides on a Telnet connection should expect to receive and process control characters. I'll show you how to do this later on when I create the Telnet protocol class.

Telnet Options

Telnet has a system that enables you to configure a server or client by using specific options . A Telnet option can either be on or off on either the client or the server.

For example, there is an option named "echo", and when it is on within the server, the server echoes every character it receives from the client back to the client. If echo is off in the server, it does not immediately send back whatever it receives. On the client side, if echo is on, the client echoes every character it receives to the screen, and so on. Different clients support different default modes, but you'll find that most of them use local-echo by default. If you couldn't see what you were typing in Demo 6.1, you're probably using a client that has disabled local-echo by default.

NOTE

There's a certain built-in Telnet client out there that millions of people have on their operating systems, which shall remain nameless! (Okay, I confess, it's Windows XP's Telnet client.) This client doesn't support echo options properly. You can tell the client to stop echoing, and it gladly obliges, but if you tell it to turn echo back on, it ignores you. I have no idea why it does this, but this is one of the reasons I decided not to bother too much with Telnet options.

Telnet options are represented as 3-byte codes within a stream of text. The first character of an option is always 0xFF, or 255 in decimal. The next character can be one of the four codes listed in Table 6.1.

This seems like a good way to negotiate which options are available, and then customize server output based on what you know the client can handle, but alas, it doesn't quite work out that way.

You see, in a network environment, you don't have control over the client. You can tell the client to do things, but it doesn't have to listen. Even worse , you can tell the client to do things, and it can reply, "Okay, I'm doing it." But in actuality, it may just be ignoring you.

Table 6.1. Telnet Option Operation Types

Value

Name

Meaning

251 (0xFB)

WILL

The sender of the command enabled an option.

252 (0xFC)

DO

The sender of the command wants the receiver to enable an option.

253 (0xFD)

WONT

The sender of the command disables or refuses to enable an option.

254 (0xFE)

DONT

The sender of the command wants the receiver to disable an option.


I've been playing around with several Telnet clients for a while, and I'm sick of options. It's amazing how many clients out there just outright ignore options altogether, and other clients gleefully turn off echoing, but absolutely refuse to turn echoing back on.

It's madness, and you're much better off ignoring options completely. Yeah, it's not proper, but for MUDs, the options really aren't useful anyway. It's useful to know that the options exist, however.

VT100 Terminal Codes

I previously told you about terminals that were used to access servers and mainframes. Most terminals supported the base ASCII codes, but they wanted to add new things to the termi-nalsthings that weren't supported by ASCII. Of course, the emergence of many new terminals at about the same time with no standard for extended features resulted in a huge mess of incompatible terminal types.

Years down the road, the ANSI group decided to settle on the DEC VT100 standard for extended terminal control codes. VT100 is pretty much supported by every Telnet client in existence, so you can assume that Telnet clients support the control codes.

Among other things, the VT100 has codes for color , cursor control, and clearing text from the screen. All VT100 control codes start with the ASCII "escape" character, 0x1B, or 27 in decimal, and after that most of them have the left-square- bracket "[". Table 6.2 lists the most common codes.

Table 6.2. Common VT100 Control Codes

Code

Meaning

<ESC>[0m

Reset all color and text attributes

<ESC>[1m

Bright/bold color

<ESC>[2m

Dim/unbold color

<ESC>[4m

Underline text

<ESC>[5m

Blinking text

<ESC>[7m

Reversed color text (foreground and background colors are swapped)

<ESC>[8m

Hidden text (characters not displayed)

<ESC>[30m

Black foreground color

<ESC>[31m

Red foreground color

<ESC>[32m

Green foreground color

<ESC>[33m

Yellow foreground color

<ESC>[34m

Blue foreground color

<ESC>[35m

Magenta foreground color

<ESC>[36m

Cyan foreground color

<ESC>[37m

White foreground color

<ESC>[40m

Black background color

<ESC>[41m

Red background color

<ESC>[42m

Green background color

<ESC>[43m

Yellow background color

<ESC>[44m

Blue background color

<ESC>[45m

Magenta background color

<ESC>[46m

Cyan background color

<ESC>[47m

White background color

<ESC>[<R>;<C>H

Move the cursor to row <R> and column <C>, or to the "Home" position if both <R> and <C> are omitted [*]

<ESC>[<C>A

Move the cursor up <C> lines, or one line if <C> is omitted. [*]

<ESC>[<C>B

Move the cursor down <C> lines, or one line if <C> is omitted. [*]

<ESC>[<C>C

Move the cursor forward <C> spaces, or just one if <C> is omitted. [*]

<ESC>[K

Erases everything after the cursor on the current line

<ESC>[1K

Erases everything before the cursor on the current line

<ESC>[2K

Erases the current line

<ESC>[J

Erases every line below the current line

<ESC>[1J

Erases every line above the current line

<ESC>[2J

Erases the entire screen


[*] The values <R> and <C> are meant to be replaced by actual numbers .

[*] The values <R> and <C> are meant to be replaced by actual numbers.

[*] The values <R> and <C> are meant to be replaced by actual numbers.

[*] The values <R> and <C> are meant to be replaced by actual numbers.

Load Demo 6.1 again, and log into the demo by using your favorite Telnet client. This time, I want you to play around with the VT100 codes (by pressing the Esc key), and then the rest of the code. For example, "<ESC>[31m" will make your text turn red, and it will stay red until you reset it or change the color.

The codes listed in the table are pretty much all you're going to need. There are other codes available, but they aren't as useful for MUDs; they're mostly obscure commands that don't do anything useful.

[ LiB ]


MUD Game Programming
MUD Game Programming (Premier Press Game Development)
ISBN: 1592000908
EAN: 2147483647
Year: 2003
Pages: 147
Authors: Ron Penton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net