// Concurrent TCP Echo Server
Server Side Program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
int main() {
int sockfd, newsockfd, n;
socklen_t len;
char buff[512];
struct sockaddr_in ser_addr, cli_addr;
// Ignore zombie processes (child exit)
signal(SIGCHLD, SIG_IGN);
// Creating TCP socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket error");
exit(1);
// Initializing server address
memset(&ser_addr, 0, sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(8810);
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// Binding
if (bind(sockfd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0) {
perror("bind error");
exit(1);
// Listening
listen(sockfd, 5);
printf("Server is waiting for connections...\n");
len = sizeof(cli_addr);
while (1) {
// Accepting a client connection
if ((newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &len)) < 0) {
perror("accept error");
continue; // continue to accept next connection
printf("Connected to client: %s:%d\n",
inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
// Create child process for this client
if (fork() == 0) {
// Child process handles client
close(sockfd); // child does not need the listening socket
while (1) {
n = read(newsockfd, buff, sizeof(buff) - 1);
if (n <= 0) {
printf("Client disconnected.\n");
close(newsockfd);
exit(0);
buff[n] = '\0';
printf("Message from client: %s\n", buff);
if (strncmp(buff, "exit", 4) == 0) {
printf("Closing connection with client...\n");
close(newsockfd);
exit(0);
// Echo back
write(newsockfd, buff, n);
// Parent process
close(newsockfd); // parent does not need this socket
close(sockfd);
return 0;
Client Side Program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int sockfd, n;
char buff1[512], buff2[512];
struct sockaddr_in serv_addr;
// Creating TCP socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket error");
exit(1);
// Initializing server address
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8810);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // loopback for testing
// Connecting to server
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connect error");
exit(1);
printf("Enter the message to be sent:\n");
fflush(stdout);
// Reading message from keyboard
n = read(0, buff1, sizeof(buff1) - 1);
if (n < 0) {
perror("read error");
close(sockfd);
exit(1);
buff1[n] = '\0'; // null terminate
printf("Message sent to the server: %s\n", buff1);
// Sending message to server
write(sockfd, buff1, n);
if (strncmp(buff1, "exit", 4) == 0) {
printf("Client is exiting...\n");
close(sockfd);
exit(0);
// Receiving message from server
n = read(sockfd, buff2, sizeof(buff2) - 1);
if (n < 0) {
perror("read error");
close(sockfd);
exit(1);
buff2[n] = '\0'; // null terminate
printf("Message received from the server: %s\n", buff2);
// Closing socket
close(sockfd);
return 0;