Telnet++
3.1.0.2
A C++ library for interacting with Telnet streams
|
Telnet++ is an implementation of the Telnet Session Layer protocol that is used primarily to negotiate a feature set between a client and server, the former of which is usually some kind of text-based terminal, Commonly used terminals include Xterm, PuTTY, and a whole host of Telnet-enabled MUD clients including Tintin++, MushClient, and more.
Telnet++ requires a C++17 compiler and the following libraries:
Telnet++ can be installed from source using CMake. This requires Boost, GSL-Lite and any other dependencies to have been installed beforehand, using their own instructions, or for the call to cmake --configure
to be adjusted appropriately (e.g. -DBOOST_ROOT=...
or -Dgsl-lite_DIR=...
). If you do not wish to install into a system directory, and thus avoid the use of sudo, you can also pass -DCMAKE_INSTALL_PREFIX=...
into the cmake --configure
call.
git clone https://github.com/KazDragon/telnetpp.git && cd telnetpp mkdir build && cd build cmake --configure -DCMAKE_BUILD_TYPE=Release .. cmake --build . sudo cmake --install .
Telnet++ is automatically tested with MSVC 2019 and GNU g++ 7.5.
The protocol has three basic elements, all of which are accessed by using the 0xFF character called "Interpret As Command", or IAC.
Without needing to negotiate any capabilities, Telnet offers some out-of-the-box commands. These include Are You There, which is usually sent by the client to provoke a response from an otherwise-busy server; Erase Line, which could be used in interative applications to cancel a set of input, and several other commands used for negotiations between options.
Commands are represented by the telnetpp::command class.
The Telnet protocol describes a model whereby the client and server maintain separate lists of features, called "options", which can be enabled or disabled by the remote side. Individual options may each be described as "server" or "client" options, and server and client options may be mixed on each side of the connection. It is even possible in some cases that both sides of the connection can be both client and server for the same option. These options are negotiated by using the commands DO, DONT, WILL and WONT.
The various Telnet option specifications are not consistent in what is considered a server and what is considered a client, but for the purposes of this library, the server is considered as the side of the connection that does the thing, and the client is the side of the connection that wants the thing. That is, the server reacts to DO and DONT and sends WILL and WONT, and the client reacts to WILL and WONT and sends DO and DONT.
Negotiations are represented by the telnetpp::negotiation class.
After an option has been negotiated, a new channel opens up to be able to communicate in an option-specific way to the remote terminal. These are called subnegotiations, and each protocol defines its own sub-protocol. For example, the NAWS (Negotiate About Window Size) sends five bytes when reporting window size, the first of which represents an "IS" token, and the following four bytes represent two two-byte pairs that are the window extends.
Subnegotiations are represented by the telnetpp::subnegotiation class.
A telnetpp::element is a variant that may contain a command, a negotiation, a subnegotiation, or just a plain sequence of bytes representing non-Telnet-specific input/output.
The Telnet++ library does not impose any requirement on any kind of data stream API. In order to accomplish this, it makes heavy use of a channel concept. See the telnetpp::session class for an in-depth explanation of how this works.
As alluded to earlier, each distinct feature is represented by either a telnetpp::client_option or a telnetpp::server_option. These both enjoy the same API; they only differ in the underlying protocol. The user needs to know little about which actual negotiations and commands are sent. There are two key functions and one signal for the option classes:
All of the above can be quite complicated to manage, so Telnet++ provides the telnetpp::session class. This is the key abstraction of the Telnet++ library, and is used to manage an entire Telnet feature set for a connection. This is accomplished by "install"ing handlers for commands and options:
Receiving data is slightly more complex since it is asynchronous and so requires a callback that is called when data is received.