0% found this document useful (0 votes)
4 views17 pages

Lab Assignment 1

The document contains code for a server and client implementation using sockets in C, including functionalities for simple message exchange and chat between a server and client. It includes multiple versions of server and client code, demonstrating different approaches to handle connections and communication, such as using select() for non-blocking I/O. The revised versions improve chat functionality and user interaction by allowing simultaneous input and output handling.

Uploaded by

PIYUSH
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views17 pages

Lab Assignment 1

The document contains code for a server and client implementation using sockets in C, including functionalities for simple message exchange and chat between a server and client. It includes multiple versions of server and client code, demonstrating different approaches to handle connections and communication, such as using select() for non-blocking I/O. The revised versions improve chat functionality and user interaction by allowing simultaneous input and output handling.

Uploaded by

PIYUSH
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Lab Assignment 1

Name - Piyush Kumar Jha


Entry No.- 2021uce0067

1.> SERVER_SIMPLE.C
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>

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


{
// Step 1: Create a server socket
// socket() creates a new socket and returns a file descriptor (integer) representing it.
// Arguments:
// - AF_INET: Specifies IPv4 addressing
// - SOCK_STREAM: Specifies TCP (stream-based) communication
// - 0: Use the default protocol for the specified type (TCP in this case)
int servSockD = socket(AF_INET, SOCK_STREAM, 0);
if (servSockD < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}

// Step 2: Prepare a message to send to the client


// The message will be sent to the client upon connection.
char serMsg[255] = "Message from the server to the client 'Hello Client'";

// Step 3: Define server address structure


// sockaddr_in is used to define the address for the server socket.
struct sockaddr_in servAddr;
servAddr.sin_family = AF_INET; // Use IPv4 addressing
servAddr.sin_port = htons(9001); // Port number (convert to network byte order using htons)
servAddr.sin_addr.s_addr = INADDR_ANY; // Accept connections on any IP address for the host

// Step 4: Bind the socket to the server address


// bind() associates the socket (servSockD) with the specified IP address and port.
if (bind(servSockD, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0) {
perror("Binding failed");
close(servSockD);
exit(EXIT_FAILURE);
}

// Step 5: Put the server socket into listening mode


// listen() marks the socket as passive, meaning it will wait for incoming connections.
// The second argument specifies the maximum number of pending connections in the queue.
if (listen(servSockD, 1) < 0) {
perror("Listening failed");
close(servSockD);
exit(EXIT_FAILURE);
}

// Step 6: Accept a connection from a client


// accept() waits for a client to connect and returns a new socket descriptor for communication with
the client.
int clientSocket = accept(servSockD, NULL, NULL);
if (clientSocket < 0) {
perror("Accept failed");
close(servSockD);
exit(EXIT_FAILURE);
}

// Step 7: Send a message to the connected client


// send() transmits data through the client socket.
// Arguments:
// - clientSocket: The socket descriptor for the connected client
// - serMsg: The message to send
// - sizeof(serMsg): The length of the message
// - 0: Flags (not used here, so set to 0)
if (send(clientSocket, serMsg, sizeof(serMsg), 0) < 0) {
perror("Sending message failed");
}

// Step 8: Clean up and close sockets


close(clientSocket); // Close the client socket
close(servSockD); // Close the server socket

return 0; // Exit the program


}

2.> SERVER_CHAT_2.C
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr

// Function designed for chat between client and server


void func(int connfd)
{
char buff[MAX]; // Buffer for storing messages
int n; // Variable for indexing buffer

// Infinite loop for chat


for (;;) {
bzero(buff, MAX); // Clear the buffer to remove old data

// Read the message from the client and copy it into the buffer
read(connfd, buff, sizeof(buff));
// Print the received message
printf("From client: %s\t To client: ", buff);
bzero(buff, MAX); // Clear the buffer again before sending response

n = 0;
// Read server input (response message) from the terminal
while ((buff[n++] = getchar()) != '\n')
;

// Send the buffer (server's response) to the client


write(connfd, buff, sizeof(buff));
// If the message contains "exit", terminate the server and chat
if (strncmp("exit", buff, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
}

// Driver function (entry point of the program)


int main()
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli; // Structures to hold server and client address information

// Socket creation and verification


sockfd = socket(AF_INET, SOCK_STREAM, 0); // Create a TCP socket
if (sockfd == -1) {
printf("Socket creation failed...\n");
exit(0);
} else
printf("Socket successfully created..\n");

bzero(&servaddr, sizeof(servaddr)); // Clear the server address structure

// Assign IP and port to the server address


servaddr.sin_family = AF_INET; // IPv4 addressing
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // Accept connections on any local interface
servaddr.sin_port = htons(PORT); // Port number in network byte order

// Bind the socket to the server address and port


if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("Socket bind failed...\n");
exit(0);
} else
printf("Socket successfully binded..\n");

// Put the server socket into listening mode


if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
} else
printf("Server listening..\n");

len = sizeof(cli); // Length of the client address structure

// Accept a connection from a client


connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("Server accept failed...\n");
exit(0);
} else
printf("Server accepted the client...\n");

// Function for chatting between client and server


func(connfd);

// Close the server socket after chat is complete


close(sockfd);
}
3.> CLIENT_CHAT_2.C
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr

// Function for chat between client and server


void func(int sockfd)
{
char buff[MAX]; // Buffer for messages
int n; // Variable to index the buffer

// Infinite loop for chat


for (;;) {
bzero(buff, sizeof(buff)); // Clear the buffer to remove old data

// Read input from the client user


printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n') // Read character by character until newline
;

// Write the user's input to the server


write(sockfd, buff, sizeof(buff));

// Clear the buffer and read the response from the server
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
// Print the server's response
printf("From Server : %s", buff);

// Check if the server sent "exit". If yes, terminate the chat.


if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}
}

int main()
{
int sockfd; // Socket file descriptor
struct sockaddr_in servaddr; // Server address structure

// Step 1: Create a socket


// socket() creates a new socket and returns a file descriptor
// Arguments:
// - AF_INET: Use IPv4 addressing
// - SOCK_STREAM: Use TCP (stream-based) communication
// - 0: Use the default protocol for the specified type (TCP)
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) { // If socket creation fails, terminate the program
printf("socket creation failed...\n");
exit(0);
} else
printf("Socket successfully created..\n");

bzero(&servaddr, sizeof(servaddr)); // Clear the server address structure

// Step 2: Assign IP and port to the server address structure


servaddr.sin_family = AF_INET; // Use IPv4 addressing
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Use localhost IP (127.0.0.1)
servaddr.sin_port = htons(PORT); // Assign port number (convert to network byte order)

// Step 3: Connect the client socket to the server socket


if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) { // Attempt to connect
printf("connection with the server failed...\n");
exit(0); // Terminate if the connection fails
} else
printf("connected to the server..\n");

// Step 4: Chat function for communication between client and server


func(sockfd);

// Step 5: Close the socket after the chat ends


close(sockfd);
}

4.> CLIENT_SIMPLE.C
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>

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


{
// Step 1: Create a socket
// socket() creates a new socket and returns a file descriptor.
// Arguments:
// - AF_INET: Specifies IPv4 addressing
// - SOCK_STREAM: Specifies TCP (stream-based) communication
// - 0: Use the default protocol for the specified type (TCP in this case)
int sockD = socket(AF_INET, SOCK_STREAM, 0);

// Step 2: Define the server address


struct sockaddr_in servAddr; // Structure to hold server address

servAddr.sin_family = AF_INET; // Use IPv4 addressing


servAddr.sin_port = htons(9001); // Specify port number (convert to network byte order
using htons)
servAddr.sin_addr.s_addr = INADDR_ANY; // Use any available local IP address

// Step 3: Connect to the server


// connect() attempts to establish a connection to the server specified by servAddr
int connectStatus = connect(sockD, (struct sockaddr*)&servAddr, sizeof(servAddr));

// Step 4: Check if the connection was successful


if (connectStatus == -1) {
// If connection fails, print an error message and exit
printf("Error...\n");
} else {
// Step 5: If connection is successful, receive data from the server
char strData[255]; // Buffer to store the received data

// recv() receives data from the server through the socket


recv(sockD, strData, sizeof(strData), 0);

// Print the received message


printf("Message: %s\n", strData);
}
return 0; // Exit the program
}

Revised Server Code (server_chat_2.c)


#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr

void handle_chat(int connfd)


{
char buff[MAX];
int n;
fd_set readfds;

for (;;) {
FD_ZERO(&readfds);
FD_SET(0, &readfds); // Standard input (stdin)
FD_SET(connfd, &readfds); // Client socket

// Monitor stdin and connfd


select(connfd + 1, &readfds, NULL, NULL, NULL);

if (FD_ISSET(0, &readfds)) { // User input


bzero(buff, MAX);
n = 0;
printf("You: ");
while ((buff[n++] = getchar()) != '\n');
write(connfd, buff, sizeof(buff));
if (strncmp("exit", buff, 4) == 0) {
printf("Server exiting...\n");
break;
}
}

if (FD_ISSET(connfd, &readfds)) { // Incoming message from client


bzero(buff, MAX);
read(connfd, buff, sizeof(buff));
printf("Client: %s", buff);
if (strncmp("exit", buff, 4) == 0) {
printf("Client exited. Closing connection...\n");
break;
}
}
}
}

int main()
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;

// Socket creation
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("Socket creation failed...\n");
exit(0);
} else
printf("Socket successfully created...\n");
bzero(&servaddr, sizeof(servaddr));

// Assign IP and port


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);

// Bind socket
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("Socket bind failed...\n");
exit(0);
} else
printf("Socket successfully binded...\n");

// Listen for clients


if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
} else
printf("Server listening...\n");

len = sizeof(cli);

// Accept client connection


connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("Server accept failed...\n");
exit(0);
} else
printf("Server accepted the client...\n");
// Handle chat
handle_chat(connfd);

// Close sockets
close(connfd);
close(sockfd);
}

Revised Client Code (client_chat_2.c)


#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr

void handle_chat(int sockfd)


{
char buff[MAX];
int n;
fd_set readfds;

for (;;) {
FD_ZERO(&readfds);
FD_SET(0, &readfds); // Standard input (stdin)
FD_SET(sockfd, &readfds); // Server socket

// Monitor stdin and sockfd


select(sockfd + 1, &readfds, NULL, NULL, NULL);

if (FD_ISSET(0, &readfds)) { // User input


bzero(buff, MAX);
n = 0;
printf("You: ");
while ((buff[n++] = getchar()) != '\n');
write(sockfd, buff, sizeof(buff));
if (strncmp("exit", buff, 4) == 0) {
printf("Client exiting...\n");
break;
}
}

if (FD_ISSET(sockfd, &readfds)) { // Incoming message from server


bzero(buff, MAX);
read(sockfd, buff, sizeof(buff));
printf("Server: %s", buff);
if (strncmp("exit", buff, 4) == 0) {
printf("Server exited. Closing connection...\n");
break;
}
}
}
}

int main()
{
int sockfd;
struct sockaddr_in servaddr;

// Socket creation
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("Socket creation failed...\n");
exit(0);
} else
printf("Socket successfully created...\n");
bzero(&servaddr, sizeof(servaddr));

// Assign IP and port


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);

// Connect to server
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("Connection with the server failed...\n");
exit(0);
} else
printf("Connected to the server...\n");

// Handle chat
handle_chat(sockfd);

// Close socket
close(sockfd);
}
Explanation of Changes
1. Added select():
o Allows simultaneous monitoring of standard input and the socket for non-blocking
communication.
o Ensures that both the user can type messages and receive responses without blocking.
2. Graceful Exit:
o Both client and server terminate the chat if either sends "exit".
3. Loop for Continuous Communication:
o Both client and server use infinite loops to send and receive messages until "exit" is
encountered.

You might also like