Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Python

A Simple Telnet Server in Python

4.43/5 (5 votes)
26 Mar 2011GPL34 min read 55.5K   1.4K  
A simple Telnet server written using Python

Introduction

This server uses the Telnet protocol which is not used as much nowadays because HTTP has taken its place. However, it is very simple and light. It does not need a heavy server or complicated methods to write dynamic functions. Almost everything to be sent is based on text. I run a Windows server and I made this program for maintaining the Windows server. This program can be used as a simple monitoring program. You can check whether your server is OK or not via Telnet. The things you need to do are simply add a script or modify some Python code.

Background

This server is written using the Telnet protocol, ANSI code, and ZModem. These are not common these days. So if you were familiar with this protocol, you could modify it for your purposes. If you know the Python language, you can understand the code easily.

Using the Server

1. Writing Scripts

This server uses a script to add user functions. The script consists of two parts. One is the text and the other is the action macro. The sever sends the text to the client without any change, but the action macro does not. The server parses the action macro which starts "{%" and ends with "%}". Between these delimiters, the server parses the string and extracts the function name and type. If the string starts with "ansi", it means the server will call functions in STANSICode. If the string starts with "set", it means the server will get some data from the client. If the string starts with "get", it means the server will call the function and get the return value which will be sent to the client.

Python
{%
ansi:Move(12,14);
set:STLoginID;
set:STLoginPassword;
%}

2.Writing a User-function

After parsing the script, the server will call the user function in STUserHandler. If the user function is the "set" type, the function has to have two parameters (client and data). client is the client object to know which client called this function. data is the data from the client.

Python
def STLoginID(client, data):
    data = getAlphabetNumber(data)
    if data:
        client.user_id = data
        client.send(STANSICode().Move(12, 15))
        client.sendDirectly(getIACCommand('WILL','ECHO'))
        return ""
    else:
        return "repeat"
    if client != None:
        return "root"
    return "repeat"

Based on the function's return value, the client handler acts differently. If the user function returns "repeat", the handler does not change the script. It keeps the status of the script and handles only data from the client. I will list the various types below:

Return typeAction
script keywordgo to the script that has "KEYWORD"
refreshclean the screen and go to the same script
remainkeep the script without clearing the screen
repeatdo nothing, just receive data
rootgo to root script

3.Client Information

When the server accepts the client, the server creates each client object. Each client has these private data: user id, nick_name, password, so on... page_index means the current page index in list. keyword means the current script to be shown in the screen. set_commands is a vector that has a list of functions which will be called. set_post is the same as set_commands but the timing is different.

Python
class STClient():
    def __init__(self):
        self.user_id = 'GUEST'
        self.nick_name = 'GUEST'
        self.password = ''
        self.keyword = 'root'
        self.set_commands = []
        self.set_post = []
        self.status = "none"
        self.zmodem = None
        self.page_index = 0
        self.client_data = [] # this list for an user
        self.command = None
        client_list.append(self)
...

4. Class Description

Here is a short explanation of the key classes:

Class nameRule
STClientHandlerHandled a client with scripts
STClientSocketIt is a client socket to correspond with a client object. This class is created using (server = ThreadingTCPServer). When a client socket is created, the thread is also created. So each client socket has a thread to send and receive data.
STDatabaseHandling member account by SQLite3, creating a table, updating member status.
STSettingsWriting default settings values

Additional Useful Class

Simple Telnet Server has some additional features, ZModem and a Command Shell. ZModem is for uploading and downloading the file from a client. I made this module taking help from this document: http://www.ifremer.fr/lpo/gliders/donnees_tt/tech/protocoles/readme_zmodem_doc.pdf.

1. ZModem

Python
download = ZModem.zmodem(client) # Create Zmodem instance
download.send_files(filelist) # send files in filelist to the client

upload = ZModem.zmodem(client) # Create Zmodem instance
upload.receive_files(telnet_pds_path) # get and save the file to telnet_pds_path

2. Command Shell

This is the DOS Command Shell for Python. I made it using pywin32 for creating a process and a pipe. Python popen has blocking issue in reading data from a pipe. I modified this base code from pywin32 demo-code runproc.py. You can use this module as a stand-alone batch tool.

Python
command = Command() # create Cmd instance
command.run() # run thread and "cmd.exe" process
command.sendCommand("exit") # send command to cmd.exe through pipe and telnet
command.getResult()# get text after executing the command
command.end() # finish the thread

3. More Features

This server supports simple login, admin scripts, and a very, very simple chat module. And in the prompt, it can send a message to the user directly.

History

  • 0.1: This is still a beta version. I know it is not complete, this program has some known bugs and it needs more error handling. But I think it is quite usable, at least in my case.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)