Example2: tcpecho_server Description This example implements a simple TCP echo server. It listens on Port 7 for connection requests. After a client connects, it will echo back each message that it receives. This code was intended as a simple example of a TCP server program. In order to keep the code simple, it will handle only one connection at a time. It will only return the first 255 bytes of any requests that are longer than 255 bytes. You can connect to the example echo server with another embTCP system running the TCP echo client of Example1, or you may use any other TCP echo client. While most Windows and Linux system have TCP echo server, most do not have a TCP echo client configured by default. If they have a Telnet client, then you can use Telnet to connect to Port 7 at the IP address of the echo server. Once the connection is made, the echo server will echo back anything that you type into the Telnet session. The initialization routine for all of the embTCP example programs is called example_init. For this reason, you can only link with one example at a time on an embTCP system. When example_init is called, it will create and initialize a task and begin running. Code Walkthrough In tcpecho_server.c, after a few definitions and prototypes, the next section defines the TCP task info structure and calls TK_CREATE to create the TCP echo server task. The function example_init() creates tcp echo server task. Task body tk_ts_echo waits until the network is ready and then calls tcp_secho_init. Tcp_secho_init() calls the main loop of the echo server. Tcp_secho_init() only returns if there is an error setting up the listening socket. If it does return, the task will be deleted. The tcp_secho_init() routine does the following: * Sets up a socket address structure for listening on port 7 for a connection request from any IP4 address. * Calls t_socket(), t_bind() and t_listen so that it can begin listening for connection requests. * Uses t_setsocketopt to put the socket in non-blocking mode. This is important because the echo server uses two sockets: one for listening for connection requests and another that is created to listen for incoming messages from an accepted connection. If the listening socket were to block waiting for another connection request, the echo server would not be able to service the requests for the connected socket. * Allocates a read buffer and calls tcp_echo_recv(); The tcp_echo_recv() routine does the following: * Goes into a loop. The "while (1)" expression means it will only exit when "return" is called. * Calls t_accept() to check for and accept any received connection request. If the return is a valid socket and we are not already servicing a different connection (This echo server handles only one connection at a time), then we set the global esvr_sock to this newly accepted socket. * Call t_recv to read any messages received on esvr_sock. A return of 0 means the peer closed the socket. A zero return causes us to close esvr_sock, but to continue listening for new connections on elisten_sock. * If len > 0, we call tesvrecho() to echo back the received data. * Sleeps for 2 ticks before going back around the loop. The tesvrecho() routine does the following: * Calls t_send() and, if necessary, loops until all of the data is sent. The loop is necessary because if the system is congested, the first call to t_send() may return EWOULDBLOCK or it may send only part of the data. * If only part of the data was sent, we advance the buffer pointer, subtract bytessent from bytestosend, and yield the system briefly before trying again.