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.