Recently, for the Manchester Raspberry Jam, I decided to write an extremely simple MUD game which could be run on the Raspberry Pi. The aim was to create something fun that might spark curiosity for someone learning to program. The code is up on GitHub.
Getting the server to work with Microsoft's Telnet client that ships with Windows (or doesn't, as is currently the case), proved to be a bit of a pain. In Linux I could connect to the server, type a command, and as I typed I would be able to see the letters appearing in my local terminal. When I hit enter, the server would receive the whole line I had typed. All good.
In Windows, however, the first problem I discovered was that the telnet client is no longer installed by default for Vista onwards. Vista / 7 / 8 users have to follow this guide to enable it.
The next oddity I found was that telnet would begin echoing characters locally, and then stop, leaving me typing blind. I did some Googling to find the list of telnet options in an attempt to work out whether there was some negotiation the server was supposed to make with the client in order to get it to echo properly.
Telnet's option code 1 is "echo", but this refers to remote echoing. That is, whether or not the machine should send back the characters it receives from the other end of the connection. I wondered whether the server needed to explicitly declare that it wasn't going to do any remote echoing:
IAC WONT echo
But this didn't appear to make any difference.
Then I discovered that the telnet client has its own local echo setting that can be turned on and off:
telnet> set localecho on
However, this still didn't explain why local echoing worked initially but stopped working after a moment. More Googling eventually led me to this forum thread, where it was revealed that Microsoft Telnet does some weird mode-switching based on what it receives from the server. This behaviour can be summarised as follows:
- By default, the local echo option is set to off
- However, this option is overridden when telnet first starts, and it will begin echoing characters locally anyway
- Telnet switches out of this initial overriding mode as soon as it receives its first command code from the server
- It then respects the local echo option, ceasing to echo characters locally until the user turns the option on.
In my case, I had been sending the "are you there" command periodically in order to check the connection status. Windows telnet was stopping its local echo as soon as one of these arrived. For my particular situation, the best solution was simply to stop sending any commands to client at all. This was the simplest way to guarantee that the client would echo locally by default.
Finally the last hurdle I encountered was the different way Microsoft telnet was handling typing. In Linux, the client buffered the message locally as the user typed and only sent it once enter as pressed. In Windows, each character was being sent to the server as soon as it was typed. This even included backspace as the user edited their message. My solution was to buffer the input on the server, making sure to remove the previous character on receipt of a backspace code.