TCP Echo Server-Client Program

This section presents a simple echo server-client program using TCP. The program is denoted by C13.2. For simplicity, we assume that both the server and client run on the same computer, and the server port number is hard coded as 1234. The following chart shows the algorithms and sequence of actions of the TCP server and client.

/******** C13.2.a: TCP server.c file ********/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <netdb.h>

#define MAX          256

#define SERVER_HOST “localhost”

#define SERVER_IP “127.0.0.1”

#define SERVER_PORT 1234

struct sockaddr_in server_addr, client_addr;

int mysock, csock;    // socket descriptors

int r, len, n;            // help variables

int server_init()

{

printf(“================== server init ======================\n”);

// create a TCP socket by socket() syscall

printf(“1 : create a TCP STREAM socket\n”);

mysock = socket(AF_INET, SOCK_STREAM, 0);

if (mysock < 0){

printf(“socket call failed\n”); exit(1);

}

printf(“2 : fill server_addr with host IP and PORT# info\n”);

// initialize the server_addr structure

server_addr.sin_family = AF_INET;                  // for TCP/IP

server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // This HOST IP

server_addr.sin_port = htons(SERVER_PORT); // port number 1234

printf(“3 : bind socket to server address\n”);

r = bind(mysock,(struct sockaddr*)&server_addr,sizeof(server_addr));

if (r < 0){

printf(“bind failed\n”); exit(3);

}

printf(” hostname = %s port = %d\n”, SERVER_HOST, SERVER_PORT);

printf(“4 : server is listening ….\n”);

listen(mysock, 5); // queue length = 5

printf(“=================== init done =======================\n”);

}

int main()

{

char line[MAX]; server_init();

while(1){ // Try to accept a client request

printf(“server: accepting new connection ….\n”);

// Try to accept a client connection as descriptor newsock

len = sizeof(client_addr);

csock = accept(mysock, (struct sockaddr *)&client_addr, &len);

if (csock < 0){

printf(“server: accept error\n”); exit(1);

}

printf(“server: accepted a client connection from\n”);

printf(“——————————————– \n”);

printf(“Clinet: IP=%s port=%d\n”,

inet_ntoa(client_addr.sin_addr.s_addr),

ntohs(client_addr.sin_port));

printf(“——————————————– \n”);

// Processing loop: client_sock <== data ==> client

while(1){

n = read(csock, line, MAX);

if (n==0){

printf(“server: client died, server loops\n”);

close(csock);

break;

}

// show the line string

printf(“server: read n=%d bytes; line=%s\n”, n, line);

// echo line to client

n = write(csock, line, MAX);

printf(“server: wrote n=%d bytes; ECHO=%s\n”, n, line);

printf(“server: ready for next request\n”);

}

}

}

/******** C13.2.b: TCP client.c file TCP ********/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <netdb.h>

#define MAX          256

#define SERVER_HOST “localhost”

#define SERVER_PORT 1234 struct sockaddr_in server_addr;

int sock, r;

int client_init()

{

printf(“======= clinet init ==========\n”);

printf(“1 : create a TCP socket\n”);

sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock<0){

printf(“socket call failed\n”); exit(1);

}

printf(“2 : fill server_addr with server’s IP and PORT#\n”);

server_addr.sin_family = AF_INET;

server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // localhost

server_addr.sin_port = htons(SERVER_PORT); // server port number

printf(“3 : connecting to server ….\n”);

r = connect(sock,(struct sockaddr*)&server_addr, sizeof(server_addr));

if (r < 0){

printf(“connect failed\n”); exit(3);

}

printf(“4 : connected OK to\n”);

printf(“—————————————————– \n”);

printf(“Server hostname=%s PORT=%d\n”, SERVER_HOST, SERVER_PORT);

printf(“—————————————————– \n”);

printf(“========= init done ==========\n”);

}

int main()

{

int n;

char line[MAX], ans[MAX];

client_init();

printf(“******** processing loop *********\n”);

while (1){

printf(“input a line :   “);

bzero(line, MAX);            // zero out line[ ]

fgets(line, MAX, stdin); // get a line from stdin

line[strlen(line)-1] = 0;   // kill \n at end

if (line[0]==0)              // exit if NULL line

exit(0);

// Send line to server

n = write(sock, line, MAX);

printf(“client: wrote n=%d bytes; line=%s\n”, n, line);

// Read a line from sock and show it

n = read(sock, ans, MAX);

printf(“client: read n=%d bytes; echo=%s\n”, n, ans);

}

}

Figure 13.8 shows the sample outputs of running the TCP server-client program C13.2.

Source: Wang K.C. (2018), Systems Programming in Unix/Linux, Springer; 1st ed. 2018 edition.

Leave a Reply

Your email address will not be published. Required fields are marked *