Client Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netdb.h>
#include<unistd.h>
#include<stdio.h>
: Includes the standard input-output library for functions likeprintf
.#include<stdlib.h>
: Includes the standard library for functions likeatoi
.#include<string.h>
: Includes the string library for functions likefgets
andstrlen
.#include<sys/socket.h>
: Includes definitions for socket operations.#include<netdb.h>
: Includes definitions for network database operations.#include<unistd.h>
: Includes standard symbolic constants and types, and declares miscellaneous functions such asclose
.
int main(int argc, char *argv[]) {
struct sockaddr_in server;
char send_buff[100];
char recv_buff[100];
socklen_t addr_len = sizeof(server);
int main(int argc, char *argv[])
: The main function which takes command-line arguments.argc
is the argument count andargv
is the argument vector (array of strings).struct sockaddr_in server;
: Declares a structureserver
of typesockaddr_in
to store the server's address information.char send_buff[100];
: Declares a character buffersend_buff
to store the message to be sent.char recv_buff[100];
: Declares a character bufferrecv_buff
to store the received message.socklen_t addr_len = sizeof(server);
: Declares a variableaddr_len
to store the size of the server address structure.
if(argc != 3) {
printf("Usage: %s <IP address> <port>\n", argv[0]);
return 1;
}
if(argc != 3)
: Checks if the number of arguments is not equal to 3. If not, it prints an error message indicating the correct usage and returns 1 to indicate an error.printf("Usage: %s <IP address> <port>\n", argv[0]);
: Prints the correct usage of the program.argv[0]
is the name of the program.return 1;
: Returns 1 to indicate an error and exits the program.
int socketid = socket(AF_INET, SOCK_DGRAM, 0);
if(socketid == -1) {
perror("Socket creation failed");
return 1;
}
int socketid = socket(AF_INET, SOCK_DGRAM, 0);
: Creates a socket of typeSOCK_DGRAM
(UDP).AF_INET
specifies IPv4, and0
means the protocol is chosen automatically.if(socketid == -1)
: Checks if the socket creation failed (returns -1).perror("Socket creation failed");
: Prints an error message describing the last error encountered.return 1;
: Returns 1 to indicate an error and exits the program.
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(atoi(argv[2]));
server.sin_family = AF_INET;
: Sets the address family toAF_INET
(IPv4).server.sin_addr.s_addr = inet_addr(argv[1]);
: Converts the IP address from the argument to a binary form and sets it.server.sin_port = htons(atoi(argv[2]));
: Converts the port number from host byte order to network byte order usinghtons
(host to network short) and sets it.atoi(argv[2])
converts the command-line argument (port) to an integer.
while(1) {
printf("Enter message to send: ");
fgets(send_buff, 100, stdin);
while(1)
: Creates an infinite loop to keep the connection alive.printf("Enter message to send: ");
: Prompts the user to enter a message.fgets(send_buff, 100, stdin);
: Reads up to 100 characters from the standard input (keyboard) into the buffersend_buff
.
if(sendto(socketid, send_buff, strlen(send_buff) + 1, 0, (struct sockaddr*)&server, addr_len) < 0) {
perror("Send failed");
break;
}
if(sendto(socketid, send_buff, strlen(send_buff) + 1, 0, (struct sockaddr*)&server, addr_len) < 0)
: Sends the message stored insend_buff
to the server.sendto
is used for sending data over UDP. It takes the socket descriptor, the buffer, the buffer size (length of the message plus one for the null terminator), flags (0), the address of the server, and the size of the address structure.socketid
: The socket descriptor.send_buff
: The buffer containing the message.strlen(send_buff) + 1
: The length of the buffer plus one for the null terminator.0
: Flags (not used here).(struct sockaddr*)&server
: Pointer to the server address structure.addr_len
: Size of the address structure.
perror("Send failed");
: Prints an error message if sending fails.break;
: Breaks out of the loop if sending fails.
if(recvfrom(socketid, recv_buff, 100, 0, (struct sockaddr*)&server, &addr_len) < 0) {
perror("Receive failed");
break;
}
if(recvfrom(socketid, recv_buff, 100, 0, (struct sockaddr*)&server, &addr_len) < 0)
: Receives a message from the server.recvfrom
is used for receiving data over UDP. It takes the socket descriptor, the buffer, the buffer size (100 bytes), flags (0), the address of the sender (server), and the size of the address structure.socketid
: The socket descriptor.recv_buff
: The buffer to store the received message.100
: The length of the buffer.0
: Flags (not used here).(struct sockaddr*)&server
: Pointer to the server address structure.&addr_len
: Pointer to the size of the address structure.
perror("Receive failed");
: Prints an error message if receiving fails.break;
: Breaks out of the loop if receiving fails.
printf("Server: %s\n", recv_buff);
}
printf("Server: %s\n", recv_buff);
: Prints the received message from the server.
close(socketid);
return 0;
}
close(socketid);
: Closes the socket when done.return 0;
: Returns 0, indicating that the program executed successfully.
Server Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netdb.h>
#include<unistd.h>
#include<stdio.h>
: Includes the standard input-output library for functions likeprintf
.#include<stdlib.h>
: Includes the standard library for functions likeatoi
.#include<string.h>
: Includes the string library for functions likefgets
andstrlen
.#include<sys/socket.h>
: Includes definitions for socket operations.#include<netdb.h>
: Includes definitions for network database operations.#include<unistd.h>
: Includes standard symbolic constants and types, and declares miscellaneous functions such asclose
.
int main(int argc, char *argv[]) {
struct sockaddr_in server, client;
char send_buff[100];
char recv_buff[100];
socklen_t addr_len = sizeof(client);
int main(int argc, char *argv[])
: The main function which takes command-line arguments.argc
is the argument count andargv
is the argument vector (array of strings).struct sockaddr_in server, client;
: Declares structuresserver
andclient
of typesockaddr_in
to store the server's and client's address information.char send_buff[100];
: Declares a character buffersend_buff
to store the message to be sent.char recv_buff[100];
: Declares a character bufferrecv_buff
to store the received message.socklen_t addr_len = sizeof(client);
: Declares a variableaddr_len
to store the size of the client address structure.
if(argc != 2) {
printf("Usage: %s <port>\n", argv[0]);
return 1;
}
if(argc != 2)
: Checks if the number of arguments is not equal to 2. If not, it prints an error message indicating the correct usage and returns 1 to indicate an error.printf("Usage: %s <port>\n", argv[0]);
: Prints the correct usage of the program.argv[0]
is the name of the program.return 1;
: Returns 1 to indicate an error and exits the program.
int socketid = socket(AF_INET, SOCK_DGRAM, 0);
if(socketid == -1) {
perror("Socket creation failed");
return 1;
}
int socketid = socket(AF_INET, SOCK_DGRAM, 0);
: Creates a socket of typeSOCK_DGRAM
(UDP).AF_INET
specifies IPv4, and0
means the protocol is chosen automatically.if(socketid == -1)
: Checks if the socket creation failed (returns -1).perror("Socket creation failed");
: Prints an error message describing the last error encountered.return 1;
: Returns 1 to indicate an error and exits the program.
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(atoi(argv[1]));
server.sin_family = AF_INET;
: Sets the address family toAF_INET
(IPv4).server.sin_addr.s_addr = INADDR_ANY;
: Sets the IP address to accept connections from any interface.server.sin_port = htons(atoi(argv[1]));
: Converts the port number from host byte order to network byte order usinghtons
(host to network short) and sets it.atoi(argv[1])
converts the command-line argument (port) to an integer.
if(bind(socketid, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Bind failed");
return 1;
}
if(bind(socketid, (struct sockaddr*)&server, sizeof(server)) < 0)
: Binds the socket to the address specified in theserver
structure.bind
associates the socket with the local address. If binding fails (returns a value less than 0), it prints an error message.perror("Bind failed");
: Prints an error message describing the last error encountered.return 1;
: Returns 1 to indicate an error and exits the program.
while(1) {
if(recvfrom(socketid, recv_buff, 100, 0, (struct sockaddr*)&client, &addr_len) < 0) {
perror("Receive failed");
break;
}
printf("Client: %s", recv_buff);
printf("Enter reply message: ");
fgets(send_buff, 100, stdin);
if(sendto(socketid, send_buff, strlen(send_buff) + 1, 0, (struct sockaddr*)&client, addr_len) < 0) {
perror("Send failed");
break;
}
}
while(1)
: Creates an infinite loop to keep the connection alive.if(recvfrom(socketid, recv_buff, 100, 0, (struct sockaddr*)&client, &addr_len) < 0)
: Receives a message from the client.recvfrom
is used for receiving data over UDP. It takes the socket descriptor, the buffer, the buffer size (100 bytes), flags (0), the address of the sender (client), and the size of the address structure.socketid
: The socket descriptor.recv_buff
: The buffer to store the received message.100
: The length of the buffer.0
: Flags (not used here).(struct sockaddr*)&client
: Pointer to the client address structure.&addr_len
: Pointer to the size of the address structure.
perror("Receive failed");
: Prints an error message if receiving fails.break;
: Breaks out of the loop if receiving fails.printf("Client: %s", recv_buff);
: Prints the received message from the client.printf("Enter reply message: ");
: Prompts the server user to enter a reply message.fgets(send_buff, 100, stdin);
: Reads up to 100 characters from the standard input (keyboard) into the buffersend_buff
.if(sendto(socketid, send_buff, strlen(send_buff) + 1, 0, (struct sockaddr*)&client, addr_len) < 0)
: Sends the reply message stored insend_buff
to the client.sendto
is used for sending data over UDP. It takes the socket descriptor, the buffer, the buffer size (length of the message plus one for the null terminator), flags (0), the address of the client, and the size of the address structure.socketid
: The socket descriptor.send_buff
: The buffer containing the reply message.strlen(send_buff) + 1
: The length of the buffer plus one for the null terminator.0
: Flags (not used here).(struct sockaddr*)&client
: Pointer to the client address structure.addr_len
: Size of the address structure.
perror("Send failed");
: Prints an error message if sending fails.break;
: Breaks out of the loop if sending fails.
close(socketid);
return 0;
}
close(socketid);
: Closes the socket when done.return 0;
: Returns 0, indicating that the program executed successfully.
Summary
These programs implement a simple UDP client and server that can send and receive multiple messages in a loop. The client sends a message to the server and waits for a reply, while the server waits for a message from the client, prints it, and sends a reply back. Both the client and server continue this process in a loop until an error occurs.