TCP/IP Lean: Web Servers for Embedded Systems, Second Edition

Your Telnet application needs to
open a TCP connection to the remote host,
send keyboard data and display received data, and
close the connection.
The TCP stack does most of the work: you need to set the desired remote address and port number, and the TCP state machine will take over and set up the connection. You need some way of determining the current connection state; for example, how do you know when incoming data is available? You could just poll the incoming data buffer, but a cleaner method is to set up a callback function that is called every time a significant TCP event (opening, closing, data reception) occurs. It would be even more helpful if the callbacks were segregated into two types: those applicable to clients and those applicable to servers.
If you've been following the plot so far you'll realize that, from a TCP perspective, there is very little difference between a client and a server. Both are capable of sending and receiving data and closing the connection. The only notable difference is that a client does an Active Open of a socket, using an ephemeral port number, whereas a server does a Passive Open of a well-known port number. However, from an application writer's perspective, there is a huge difference between a client and server: the client initiates the session, whereas the server merely responds to incoming requests. To make the application writer's life easier, you must draw a distinction...