0% found this document useful (0 votes)
2 views

Network_Programming_Assignment_3

This document outlines the implementation of a TCP client-server socket program in Linux using Emacs, where the client sends two integers and the server responds with their sum in concurrent mode. It includes detailed instructions for writing, compiling, and running the client and server programs, as well as handling zombie processes. Additionally, it provides commands for monitoring TCP connections and explains the various TCP states.

Uploaded by

joshuaonyango372
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Network_Programming_Assignment_3

This document outlines the implementation of a TCP client-server socket program in Linux using Emacs, where the client sends two integers and the server responds with their sum in concurrent mode. It includes detailed instructions for writing, compiling, and running the client and server programs, as well as handling zombie processes. Additionally, it provides commands for monitoring TCP connections and explains the various TCP states.

Uploaded by

joshuaonyango372
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Network Programming Assignment 3

This document provides details on implementing a TCP client-server socket program using Emacs
on Linux.
The client sends two integers, and the server replies with their sum. The server runs in concurrent
mode.

Writing the Code in Emacs (Linux)


1. Open the terminal and navigate to your project directory.
2. Open Emacs and create the client program file:
$ emacs client_add.c
3. Write the client code (see below) and save using Ctrl+X, then Ctrl+S.
4. Create the server program file:
$ emacs server_add.c
5. Write the server code (see below) and save.

Client Program (client_add.c)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define SERVER_PORT 8080


#define SERVER_IP "127.0.0.1"

int main(int argc, char *argv[]) {


int sockfd;
struct sockaddr_in server_addr;
char buffer[1024];

if (argc != 3) {
printf("Usage: %s <num1> <num2>\n", argv[0]);
return 1;
}

int num1 = atoi(argv[1]);


int num2 = atoi(argv[2]);

sockfd = socket(AF_INET, SOCK_STREAM, 0);


if (sockfd == -1) {
perror("Socket creation failed");
return 1;
}

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {


perror("Connection failed");
close(sockfd);
return 1;
}

sprintf(buffer, "%d %d", num1, num2);


send(sockfd, buffer, strlen(buffer), 0);

recv(sockfd, buffer, sizeof(buffer), 0);


printf("Server Response: Sum = %s\n", buffer);

close(sockfd);
return 0;
}

Server Program (server_add.c)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <signal.h>

#define SERVER_PORT 8080

void handle_client(int client_sock) {


char buffer[1024];
int num1, num2, sum;

recv(client_sock, buffer, sizeof(buffer), 0);


sscanf(buffer, "%d %d", &num1, &num2);

sum = num1 + num2;


sprintf(buffer, "%d", sum);
send(client_sock, buffer, strlen(buffer), 0);

close(client_sock);
}

void sigchld_handler(int signo) {


while (waitpid(-1, NULL, WNOHANG) > 0);
}

int main() {
int server_sock, client_sock;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len;
signal(SIGCHLD, sigchld_handler);

server_sock = socket(AF_INET, SOCK_STREAM, 0);


server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;

bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));


listen(server_sock, 5);
printf("Server listening on port %d...\n", SERVER_PORT);

while (1) {
client_len = sizeof(client_addr);
client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_len);

if (fork() == 0) {
close(server_sock);
handle_client(client_sock);
exit(0);
}
close(client_sock);
}

close(server_sock);
return 0;
}

Handling Zombie Processes in fork()


When using fork() to create child processes, the parent must handle terminated child
processes to prevent zombie processes. This is done using the SIGCHLD signal:

1. Call `signal(SIGCHLD, sigchld_handler);` in main().


2. Define `void sigchld_handler(int signo) { while (waitpid(-1, NULL, WNOHANG) > 0); }`
3. This ensures that terminated child processes are cleaned up automatically.

Compiling and Running the Programs


To compile the programs in Linux:
gcc client_add.c -o client
gcc server_add.c -o server -pthread

To run the server:


./server

To run the client:


./client <num1> <num2>
Example:
./client 5 10

Expected output:
Server Response: Sum = 15

Monitoring TCP Connections with netstat


To check active TCP connections:
netstat -an | grep 8080

TCP States:
1. LISTEN - Server is waiting for connections.
2. SYN_SENT - Client sent a request.
3. SYN_RECEIVED - Server received a request.
4. ESTABLISHED - Connection is active.
5. FIN_WAIT_1 - One side initiated closure.
6. TIME_WAIT - Connection is closing.
7. CLOSED - Connection terminated.

You might also like