RFC 854

Telnet Protocol Specification

πŸ“… published May 1983, from ietf

RFC 854 πŸŽ€ is called TELNET PROTOCOL SPECIFICATION ✨, and it came out of the Network Working Group in May 1983. The authors are J. Postel and J. Reynolds, both at ISI. It obsoletes NIC 18639 πŸ’…, and it specifies a standard for the ARPA Internet community. Hosts on the ARPA Internet are expected to adopt and implement this standard 🫢.

INTRODUCTION 🌸

Okay so the TELNET Protocol is basically a general, bi-directional, eight-bit byte oriented communications facility πŸ¦‹. Its main goal is giving everyone a standard way to hook up terminal devices and terminal-oriented processes to each other ✨. The protocol MAY also be used for terminal-terminal communication ("linking") and process-process communication (distributed computation). It's giving versatile energy πŸ’–.

GENERAL CONSIDERATIONS 🧚

Bestie, a TELNET connection is a Transmission Control Protocol (TCP) connection used to transmit data with interspersed TELNET control information 🌈.

The TELNET Protocol is built on three main ideas: first, the concept of a "Network Virtual Terminal"; second, the principle of negotiated options; and third, a symmetric view of terminals and processes πŸ‘‘.

  1. When a TELNET connection is first established, each end is assumed to originate and terminate at a "Network Virtual Terminal", or NVT. An NVT is an imaginary device which provides a standard, network-wide, intermediate representation of a canonical terminal. This eliminates the need for "server" and "user" hosts to keep information about the characteristics of each other's terminals and terminal handling conventions. All hosts, both user and server, map their local device characteristics and conventions so as to appear to be dealing with an NVT over the network, and each can assume a similar mapping by the other party. The NVT is intended to strike a balance between being overly restricted (not providing hosts a rich enough vocabulary for mapping into their local character sets), and being overly inclusive (penalizing users with modest terminals) πŸ“.
NOTE: The "user" host is the host to which the physical terminal is normally attached, and the "server" host is the host which is normally providing some service. As an alternate point of view, applicable even in terminal-to-terminal or process-to-process communications, the "user" host is the host which initiated the communication. πŸ™ˆ
  1. The principle of negotiated options takes cognizance of the fact that many hosts will wish to provide additional services over and above those available within an NVT, and many users will have sophisticated terminals and would like to have elegant, rather than minimal, services. Independent of, but structured within the TELNET Protocol are various "options" that will be sanctioned and MAY be used with the "DO, DON'T, WILL, WON'T" structure (discussed below) to allow a user and server to agree to use a more elaborate (or perhaps just different) set of conventions for their TELNET connection. Such options could include changing the character set, the echo mode, etc. 🧁

The basic strategy for setting up the use of options is to have either party (or both) initiate a request that some option take effect. The other party MAY then either accept or reject the request. If the request is accepted the option immediately takes effect; if it is rejected the associated aspect of the connection remains as specified for an NVT. Clearly, a party MAY always refuse a request to enable, and MUST NOT refuse a request to disable some option since all parties MUST be prepared to support the NVT πŸ’….

The syntax of option negotiation has been set up so that if both parties request an option simultaneously, each will see the other's request as the positive acknowledgment of its own ✨.

  1. The symmetry of the negotiation syntax can potentially lead to nonterminating acknowledgment loops, where each party sees the incoming commands not as acknowledgments but as new requests which must be acknowledged. πŸŒ€ To prevent such loops, the following rules prevail:

a. Parties MAY only request a change in option status; i.e., a party may not send out a "request" merely to announce what mode it is in.

b. If a party receives what appears to be a request to enter some mode it is already in, the request SHOULD NOT be acknowledged. This non-response is essential to prevent endless loops in the negotiation. It is REQUIRED that a response be sent to requests for a change of mode, even if the mode is not changed 🫠.

c. Whenever one party sends an option command to a second party, whether as a request or an acknowledgment, and use of the option will have any effect on the processing of the data being sent from the first party to the second, then the command MUST be inserted in the data stream at the point where it is desired that it take effect. (It SHOULD be noted that some time will elapse between the transmission of a request and the receipt of an acknowledgment, which MAY be negative. Thus, a host MAY wish to buffer data, after requesting an option, until it learns whether the request is accepted or rejected, in order to hide the "uncertainty period" from the user.) πŸ¦‹

Option requests are likely to flurry back and forth when a TELNET connection is first established, as each party attempts to get the best possible service from the other party 🌸. Beyond that, however, options can be used to dynamically modify the characteristics of the connection to suit changing local conditions. For example, the NVT, as will be explained later, uses a transmission discipline well suited to the many "line at a time" applications such as BASIC, but poorly suited to the many "character at a time" applications such as NLS. A server might elect to devote the extra processor overhead required for a "character at a time" discipline when it was suitable for the local process and would negotiate an appropriate option. However, rather than then being permanently burdened with the extra processing overhead, it could switch (i.e., negotiate) back to NVT when the detailed control was no longer necessary 🧚.

It is possible for requests initiated by processes to stimulate a nonterminating request loop if the process responds to a rejection by merely re-requesting the option. To prevent such loops from occurring, rejected requests SHOULD NOT be repeated until something changes. Operationally, this can mean the process is running a different program, or the user has given another command, or whatever makes sense in the context of the given process and the given option. A good rule of thumb is that a re-request SHOULD only occur as a result of subsequent information from the other end of the connection or when demanded by local human intervention πŸ‘‘.

Option designers SHOULD NOT feel constrained by the somewhat limited syntax available for option negotiation. The intent of the simple syntax is to make it easy to have options, since it is correspondingly easy to profess ignorance about them πŸ™ˆ. If some particular option requires a richer negotiation structure than possible within "DO, DON'T, WILL, WON'T", the proper tack is to use "DO, DON'T, WILL, WON'T" to establish that both parties understand the option, and once this is accomplished a more exotic syntax can be used freely. For example, a party might send a request to alter (establish) line length. If it is accepted, then a different syntax can be used for actually negotiating the line length. Such a "sub-negotiation" might include fields for minimum allowable, maximum allowable and desired line lengths. The important concept is that such expanded negotiations SHOULD never begin until some prior (standard) negotiation has established that both parties are capable of parsing the expanded syntax πŸ”₯.

In summary, WILL XXX is sent, by either party, to indicate that party's desire (offer) to begin performing option XXX, with DO XXX and DON'T XXX being its positive and negative acknowledgments. Similarly, DO XXX is sent to indicate a desire (request) that the other party (i.e., the recipient of the DO) begin performing option XXX, with WILL XXX and WON'T XXX being the positive and negative acknowledgments. Since the NVT is what is left when no options are enabled, the DON'T and WON'T responses are guaranteed to leave the connection in a state which both ends can handle. Thus, all hosts MAY implement their TELNET processes to be totally unaware of options that are not supported, simply returning a rejection (i.e., refusing) any option request that cannot be understood πŸ¦‹.

As much as possible, the TELNET protocol has been made server-user symmetrical so that it easily and naturally covers the user-user (linking) and server-server (cooperating processes) cases. It is hoped, but not absolutely REQUIRED, that options will further this intent. In any case, it is explicitly acknowledged that symmetry is an operating principle rather than an ironclad rule 🌈.

A companion document, "TELNET Option Specifications," SHOULD be consulted for information about the procedure for establishing new options πŸ“š.

THE NETWORK VIRTUAL TERMINAL πŸ’…

The Network Virtual Terminal (NVT) is a bi-directional character device. The NVT has a printer and a keyboard. The printer responds to incoming data, and the keyboard produces outgoing data which is sent over the TELNET connection and, if "echoes" are desired, to the NVT's printer as well. "Echoes" will not be expected to traverse the network (although options exist to enable a "remote" echoing mode of operation, no host is REQUIRED to implement this option) ✨. The code set is seven-bit USASCII in an eight-bit field, except as modified herein. Any code conversion and timing considerations are local problems and do not affect the NVT πŸŽ€.

TRANSMISSION OF DATA 🫢

Although a TELNET connection through the network is intrinsically full duplex, the NVT is to be viewed as a half-duplex device operating in a line-buffered mode. That is, unless and until options are negotiated to the contrary, the following default conditions pertain to the transmission of data over the TELNET connection:

  1. Insofar as the availability of local buffer space permits, data SHOULD be accumulated in the host where it is generated until a complete line of data is ready for transmission, or until some locally-defined explicit signal to transmit occurs. This signal could be generated either by a process or by a human user πŸ’œ.

The motivation for this rule is lowkey all about cost πŸ’Έ. Processing network input interrupts is expensive for some hosts, and the default NVT spec says "echoes" do not traverse the network, so it's totally reasonable to buffer some data at its source 🧺. Plenty of systems do some processing at the end of every input line (even line printers and card punches tend to work this way πŸ–¨οΈ), so the transmission should be triggered at the end of a line. BUT πŸ™ˆ a user or process may sometimes need to send data that doesn't end at a line break, so implementers are cautioned to provide methods of locally signaling that all buffered data should be transmitted immediately ⚑.

  1. When a process has completed sending data to an NVT printer and has no queued input from the NVT keyboard for further processing (i.e., when a process at one end of a TELNET connection cannot proceed without input from the other end), the process must transmit the TELNET Go Ahead (GA) command. πŸ¦‹

This rule is not intended to require that the TELNET GA command be sent from a terminal at the end of each line, since server hosts don't normally need a special signal (in addition to end-of-line or other locally-defined characters) to commence processing πŸ’…. The TELNET GA is designed to help a user's local host operate a physically half duplex terminal with a "lockable" keyboard, like the IBM 2741 πŸŽ€. A description of this type of terminal may help explain the proper use of the GA command.

The terminal-computer connection is always under control of either the user or the computer. Neither can unilaterally seize control from the other. Instead, the controlling end has to relinquish its control explicitly 🫢. At the terminal end, the hardware is built to relinquish control each time a "line" is terminated (i.e., when the user types the "New Line" key) ⌨️. When this happens, the attached (local) computer processes the input data and decides if output should be generated. If not, it returns control to the terminal. If output should be generated, the computer keeps control until all output has been transmitted.

The difficulties of using this type of terminal through the network should be obvious πŸ™ƒ. The "local" computer can no longer decide whether to retain control after seeing an end-of-line signal, because that decision can only be made by the "remote" computer that is processing the data. So the TELNET GA command gives the "remote" (server) computer a way to signal the "local" (user) computer that it's time to pass control to the user of the terminal πŸ‘‘. It should be transmitted at those times, and only at those times, when the user should be given control of the terminal. Note that premature transmission of the GA command may block output, since the user is likely to assume the transmitting system has paused, and so they won't turn the line around manually 😭.

The foregoing, of course, does not apply to the user-to-server direction of communication. In this direction, GAs may be sent at any time, but they never need to be sent. Also, if the TELNET connection is being used for process-to-process communication, GAs need not be sent in either direction. Finally, for terminal-to-terminal communication, GAs may be required in neither, one, or both directions. If a host plans to support terminal-to-terminal communication, it is suggested that the host give the user a way to manually signal that it's time for a GA to be sent over the TELNET connection. This, however, is not a requirement on the implementer of a TELNET process 🌸.

Note that the symmetry of the TELNET model requires that there is an NVT at each end of the TELNET connection, at least conceptually 🧚.

STANDARD REPRESENTATION OF CONTROL FUNCTIONS ✨

As stated in the Introduction to this document, the main goal of the TELNET protocol is a standard way of interfacing terminal devices and terminal-oriented processes through the network 🌈. Early experiences with this kind of interconnection showed that most servers implement certain functions, but the methods of invoking those functions differ wildly. For a human user who interacts with several server systems, these differences are super frustrating 😀. So TELNET defines a standard representation for five of these functions, as described below πŸ“‹. These standard representations have standard, but not required, meanings (with the exception that the Interrupt Process (IP) function may be required by other protocols which use TELNET). In other words, a system that doesn't provide the function to local users doesn't need to provide it to network users, and may treat the standard representation for the function as a No-operation πŸ™‚. On the other hand, a system that does provide the function to a local user is obliged to provide the same function to a network user who transmits the standard representation for it πŸ’–.

Interrupt Process (IP)

Many systems provide a function that suspends, interrupts, aborts, or terminates the operation of a user process πŸ›‘. This function is often used when a user thinks their process is stuck in an unending loop, or when an unwanted process has been accidentally activated. IP is the standard representation for invoking this function. Implementers should note that IP may be required by other protocols which use TELNET, so it should be implemented if those other protocols are to be supported 🧠.

Abort Output (AO)

Many systems provide a function that lets a process which is generating output run to completion (or reach the same stopping point it would reach if it ran to completion), but without sending the output to the user's terminal πŸ™Š. This function also typically clears any output that has already been produced but not yet actually printed (or displayed) on the user's terminal 🧹. AO is the standard representation for invoking this function. For example, a subsystem might normally accept a user's command, send a long text string to the user's terminal in response, and finally signal readiness to accept the next command by sending a "prompt" character (preceded by <CR><LF>) to the user's terminal. If AO is received during the transmission of the text string, a reasonable implementation would be to suppress the rest of the text string, but still transmit the prompt character and the preceding <CR><LF>. (This is possibly different from what might happen if an IP were received, since IP might cause the text string to be suppressed and an exit from the subsystem πŸšͺ.)

Server systems that provide this function should note that there may be buffers outside the system (in the network and the user's local host) that should be cleared. The appropriate way to do this is to transmit the "Synch" signal (described below) to the user system 🫧.

Are You There (AYT)

Many systems provide the user with some visible (e.g., printable) evidence that the system is still up and running πŸ‘€. The user may invoke this function when the system goes unexpectedly "silent" for a long time, because a computation took longer than the user expected, the system is under an unusually heavy load, etc. AYT is the standard representation for invoking this function πŸ“.

Erase Character (EC)

Many systems provide a function that deletes the last preceding undeleted character or "print position"* from the stream of data being supplied by the user. This is typically used to fix keyboard input when typing mistakes happen 🩹. EC is the standard representation for invoking this function.

*NOTE: A "print position" may contain several characters that are the result of overstrikes, or of sequences such as <char1> BS <char2>...

Erase Line (EL)

Many systems provide a function that deletes all the data in the current "line" of input. This is typically used to edit keyboard input 🧽. EL is the standard representation for invoking this function.

THE TELNET "SYNCH" SIGNAL 🌟

Most time-sharing systems provide mechanisms that let a terminal user regain control of a "runaway" process. The IP and AO functions described above are examples of these mechanisms πŸƒβ€β™€οΈ. When used locally, these systems have access to all of the signals the user supplies, whether they're normal characters or special "out of band" signals, like those sent by the teletype "BREAK" key or the IBM 2741 "ATTN" key πŸ”‘. This isn't necessarily true when terminals are connected to the system through the network, because the network's flow control mechanisms may cause such a signal to be buffered somewhere else, for example in the user's host πŸ₯Ί.

To counter this problem, the TELNET "Synch" mechanism is introduced. A Synch signal consists of a TCP Urgent notification, coupled with the TELNET command DATA MARK. The Urgent notification is not subject to the flow control that applies to the TELNET connection, and it's used to invoke special handling of the data stream by the process that receives it. In this mode, the data stream is immediately scanned for "interesting" signals (as defined below), and intervening data is discarded πŸ—‘οΈ. The TELNET command DATA MARK (DM) is the synchronizing mark in the data stream. It indicates that any special signal has already occurred, so the recipient can go back to normal processing of the data stream 🎯.

The Synch is sent via the TCP send operation with the Urgent flag set and the DM as the last (or only) data octet πŸ“¨.

When several Synchs are sent in rapid succession, the Urgent notifications may be merged. It's not possible to count Urgents, since the number received will be less than or equal to the number sent πŸ€·β€β™€οΈ. In normal mode, a DM is a no operation. In urgent mode, it signals the end of the urgent processing 🏁.

If TCP indicates the end of Urgent data before the DM is found, TELNET should continue the special handling of the data stream until the DM is found πŸ”.

If TCP indicates more Urgent data after the DM is found, it can only be because of a subsequent Synch. In that case, TELNET should continue the special handling of the data stream until another DM is found πŸ”.

"Interesting" signals are basically anything that's:

  • the TELNET standard representations of IP, AO, and AYT (but not EC or EL) πŸ™…β€β™€οΈ
  • the local analogs of those standard representations (if there are any) 🌸
  • all other TELNET commands πŸ’…
  • other site-defined signals that can be acted on without delaying the scan of the data stream ✨

Okay, so one effect of the SYNCH mechanism is that it throws away basically every character (except TELNET commands) between the sender of the Synch and its recipient. That's why it's the standard way to clear the data path when you need to. For example, if a user at a terminal causes an AO to be sent, the server that gets the AO (if it does that function at all) SHOULD return a Synch to the user. It's giving clean slate πŸ§ΉπŸ’–

Finally, the TCP Urgent notification is needed at the TELNET level as an out-of-band signal, right? Other protocols that use TELNET might need something similar at their own level, so a TELNET command that can be viewed as an out-of-band signal at a different level MAY be required. πŸ¦‹

By convention, the sequence [IP, Synch] is used as that kind of signal. Say some other protocol, which uses TELNET, defines the character string STOP as the analog of the TELNET command AO. A user of that protocol wants the server to process the STOP string, but the connection is blocked because the server is busy with other commands. The user SHOULD instruct their system to:

  1. Send the TELNET IP character;
  2. Send the TELNET SYNC sequence, that is: Send the Data Mark (DM) as the only character in a TCP urgent mode send operation.
  3. Send the character string STOP; and
  4. Send the other protocol's analog of the TELNET DM, if any.

The user (or process acting on their behalf) MUST transmit the TELNET SYNCH sequence of step 2 above, so the TELNET IP actually gets through to the server's TELNET interpreter. 🫢

The Urgent SHOULD wake up the TELNET process; the IP SHOULD wake up the next higher level process. 🚨

THE NVT PRINTER AND KEYBOARD ✨

The NVT printer has an unspecified carriage width and page length, and it can produce representations of all 95 USASCII graphics (codes 32 through 126). Of the 33 USASCII control codes (0 through 31 and 127), and the 128 uncovered codes (128 through 255), these are the ones with specified meaning to the NVT printer: πŸ–¨οΈ

   NAME                  CODE         MEANING

   NULL (NUL)              0      No Operation
   Line Feed (LF)         10      Moves the printer to the
                                  next print line, keeping the
                                  same horizontal position.
   Carriage Return (CR)   13      Moves the printer to the left
                                  margin of the current line.

In addition, these codes SHALL have defined, but not REQUIRED, effects on the NVT printer. Neither end of a TELNET connection MAY assume that the other party will take, or will have taken, any particular action when these are received or sent: πŸ€·β€β™€οΈ

   BELL (BEL)              7      Produces an audible or
                                  visible signal (which does
                                  NOT move the print head).
   Back Space (BS)         8      Moves the print head one
                                  character position towards
                                  the left margin.
   Horizontal Tab (HT)     9      Moves the printer to the
                                  next horizontal tab stop.
                                  It remains unspecified how
                                  either party determines or
                                  establishes where such tab
                                  stops are located.
   Vertical Tab (VT)       11     Moves the printer to the
                                  next vertical tab stop.  It
                                  remains unspecified how
                                  either party determines or
                                  establishes where such tab
                                  stops are located.
   Form Feed (FF)          12     Moves the printer to the top
                                  of the next page, keeping
                                  the same horizontal position.

All remaining codes do not cause the NVT printer to take any action. πŸ’€

The sequence "CR LF", as defined, puts the NVT at the left margin of the next print line (same as the sequence "LF CR" would, for example). BUT many systems and terminals don't treat CR and LF independently, so they have to put in real effort to simulate the effect. (For example, some terminals don't have a CR separate from the LF, but on those terminals it MAY be possible to simulate a CR by backspacing.) So the sequence "CR LF" MUST be treated as a single "new line" character and used whenever their combined action is intended. The sequence "CR NUL" MUST be used where a carriage return alone is actually desired, and the CR character MUST be avoided in other contexts. This rule gives systems a clear answer: when they have to decide whether to do a "new line" function or a multiple-backspace, the TELNET stream has a character after the CR that lets them make a rational decision. πŸ§ πŸ’…

Note that "CR LF" or "CR NUL" is REQUIRED in both directions (in the default ASCII mode), to keep the symmetry of the NVT model. Even when it's known in some situations (e.g., with remote echo and suppress go ahead options in effect) that characters aren't going to an actual printer, the protocol still requires that a NUL be inserted after a CR that isn't followed by a LF in the data stream, just for consistency. The flip side is that a NUL received in the data stream after a CR (unless options negotiations explicitly say otherwise) SHOULD be stripped out before the NVT gets mapped to the local character set. 🌈

The NVT keyboard has keys, key combinations, or key sequences for generating all 128 USASCII codes. Even though many of them have no effect on the NVT printer, the keyboard can still generate them. 🎹

On top of those codes, the NVT keyboard SHALL be capable of generating the following additional codes. Except as noted, these have defined, but not REQUIRED, meanings. Their actual code assignments are in the TELNET Command section, since they're kind of generic and SHOULD be available even when the data stream is interpreted as some other character set. 🌟

Synch

This key lets the user clear their data path to the other party. Hitting it causes a DM (see command section) to be sent in the data stream, with a TCP Urgent notification attached. The DM-Urgent pair is to have REQUIRED meaning, as defined previously. 🧹

Break (BRK)

This code exists because it's a signal outside the USASCII set that many systems already give local meaning. It's meant to indicate that the Break Key or the Attention Key was hit. Heads up though: this is meant to be a 129th code for systems that need it, NOT a synonym for the IP standard representation. ⚠️

Interrupt Process (IP)

Suspend, interrupt, abort, or terminate the process the NVT is connected to. It's also part of the out-of-band signal for other protocols that use TELNET. πŸ›‘

Abort Output (AO)

Let the current process (appear to) run to completion, but don't send its output to the user. Also, send a Synch to the user. πŸ™ˆ

Are You There (AYT)

Send back something visible (i.e., printable) to the NVT as evidence that the AYT was received. πŸ‘€

Erase Character (EC)

The recipient SHOULD delete the last preceding undeleted character or "print position" from the data stream. 🩹

Erase Line (EL)

The recipient SHOULD delete characters from the data stream back to, but not including, the last "CR LF" sequence sent over the TELNET connection. 🧽

The vibe with these "extra" keys, and also the printer format effectors, is that they SHOULD represent a natural extension of the mapping that already MUST be done from "NVT" into "local". Just like the NVT data byte 68 (104 octal) SHOULD be mapped to whatever the local code for "uppercase D" is, the EC character SHOULD be mapped to whatever the local "Erase Character" function is. πŸ”€ Also, just like the mapping for 124 (174 octal) is kind of arbitrary in an environment with no "vertical bar" character, the EL character MAY have a somewhat arbitrary mapping (or none at all) if there's no local "Erase Line" facility. πŸŽ€ Same deal for format effectors: if the terminal actually has a "Vertical Tab", then the mapping for VT is obvious. Only when the terminal does NOT have a vertical tab SHOULD the effect of VT be unpredictable. πŸ¦‹

TELNET COMMAND STRUCTURE πŸŽ€

okay so every TELNET command is at least two bytes πŸ’… It starts with the IAC escape character ("Interpret as Command"), and then comes the code for the command. The option negotiation commands are three bytes, and the third byte is the code for the option being talked about. ✨

Why this setup? bestie, it's genius 🧠 As more of the "data space" gets used (negotiations from the basic NVT, obviously), the reserved command values are less likely to collide with ordinary data bytes. Any collision would mean the data byte has to be "escaped" and pushed through the stream, which is annoying and inefficient πŸ™ˆ With the current setup, only the IAC needs doubling to send it as data. The other 255 codes can pass straight through, no escaping needed πŸ¦‹

Here are the defined TELNET commands. Heads up: these codes only mean what they mean when they come right after an IAC 🌸

   NAME               CODE              MEANING

   SE                  240    End of subnegotiation parameters.
   NOP                 241    No operation.
   Data Mark           242    The data stream portion of a Synch.
                              This should always be accompanied
                              by a TCP Urgent notification.
   Break               243    NVT character BRK.
   Interrupt Process   244    The function IP.
   Abort output        245    The function AO.
   Are You There       246    The function AYT.
   Erase character     247    The function EC.
   Erase Line          248    The function EL.
   Go ahead            249    The GA signal.
   SB                  250    Indicates that what follows is
                              subnegotiation of the indicated
                              option.
   WILL (option code)  251    Indicates the desire to begin
                              performing, or confirmation that
                              you are now performing, the
                              indicated option.
   WON'T (option code) 252    Indicates the refusal to perform,
                              or continue performing, the
                              indicated option.
   DO (option code)    253    Indicates the request that the
                              other party perform, or
                              confirmation that you are expecting
                              the other party to perform, the
                              indicated option.
   DON'T (option code) 254    Indicates the demand that the
                              other party stop performing,
                              or confirmation that you are no
                              longer expecting the other party
                              to perform, the indicated option.
   IAC                 255    Data Byte 255.
Quick reminder: the Data Mark (242) is the data stream piece of a Synch, and it's giving "pair me with a TCP Urgent notification" 🚨

CONNECTION ESTABLISHMENT πŸ¦‹

okay this part is so sweet πŸ₯Ή The TELNET TCP connection is set up between the user's port U and the server's port L. The server sits on its well known port L and waits for these connections πŸ‘‘ A TCP connection is full duplex and gets identified by its pair of ports, so one server can handle tons of simultaneous connections, all using its port L with a bunch of different user ports U. Multitasking queen behavior πŸ’œ

Port Assignment 🌈

When this protocol is used for remote user access to service hosts (aka remote terminal access), it's assigned server port 23 (27 octal). So in our notation, L=23 ✨

πŸ“¦ where this page comes from