Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 13

Connectionless Socket Server (UDP)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
Create a Socket:
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("Socket creation error");
exit(EXIT_FAILURE);
}
AF_INET: This stands for "Address Family - Internet." It specifies that the socket will be used for
communication over IPv4 networks.

SOCK_DGRAM: This specifies the socket type. In this case, it's a datagram socket, which is used for
connectionless communication, as in the case of UDP.

0: The third argument is the protocol parameter. When set to 0, it indicates that the operating system
should choose the appropriate protocol based on the socket type and address family. The OS will select
the default protocol associated with the specified socket type, which is IPPROTO_UDP (UDP) for
SOCK_DGRAM sockets.
Prepare Server Address:

struct sockaddr_in server_addr;

memset(&server_addr, 0, sizeof(server_addr));

server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT_NUMBER); // Specify the port
number
struct sockaddr_in server_addr;:
This line declares a variable named server_addr of type struct sockaddr_in.

struct sockaddr_in is used to store the information needed to identify a network endpoint using IPv4.

memset(&server_addr, 0, sizeof(server_addr));:
The memset() function is used to set a block of memory (in this case, the server_addr structure) to a specific value.

&server_addr provides the address of the server_addr structure.

The value 0 is the value that the memory will be filled with.

sizeof(server_addr) calculates the size of the server_addr structure in bytes, which ensures that the entire structure is filled
with zeros.

This line is commonly used to initialize the structure with zeros before populating it with specific values.

server_addr.sin_family = AF_INET;:
This line sets the sin_family field of the server_addr structure.
sin_family specifies the address family, and AF_INET represents IPv4.
server_addr.sin_addr.s_addr = INADDR_ANY;:
This line sets the sin_addr.s_addr field of the server_addr structure.

sin_addr holds the IP address of the socket.

INADDR_ANY is a special constant that indicates that the socket can receive incoming packets from any available
network interface on the system. This allows the server to listen on all available interfaces.

server_addr.sin_port = htons(PORT_NUMBER);:
This line sets the sin_port field of the server_addr structure.
sin_port specifies the port number of the socket.
htons(PORT_NUMBER) converts the port number to network byte order (big-endian), which is required for network
communication. htons stands for "host to network short."
Bind the Socket to the Server Address:

if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)


{
perror("Bind error");
exit(EXIT_FAILURE);
}
bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)):
The bind() function is used to associate a socket with a specific address and port.

sockfd is the socket file descriptor returned by the socket() function. It represents the socket you want to bind.

(struct sockaddr *)&server_addr is a pointer to the server_addr structure, which contains the address information you
want to bind to the socket.

sizeof(server_addr) specifies the size of the server_addr structure in bytes.


< 0:

The bind() function returns -1 if an error occurs during the binding process.
perror("Bind error");:

If bind() returns an error (i.e., -1), the perror() function is used to print an error message along with a description of the error
to the standard error stream (usually the console).
"Bind error" is the error message that will be printed.
exit(EXIT_FAILURE);:

After printing the error message, the program exits with a failure status using the exit() function.
EXIT_FAILURE is a predefined macro that indicates a non-successful termination of the program.
Receive and Echo Data:

char buffer[MAX_BUFFER_SIZE];

struct sockaddr_in client_addr;

socklen_t addr_len = sizeof(client_addr);

while (1) {
int bytes_received = recvfrom(sockfd, buffer, sizeof(buffer), 0,
(struct sockaddr *)&client_addr, &addr_len);
if (bytes_received < 0) {
perror("Receive error");
exit(EXIT_FAILURE);
}
buffer[bytes_received] = '\0'; // Add null-terminator to make it a string

printf("Received from client: %s\n", buffer);

// Echo the received data back to the client


int bytes_sent = sendto(sockfd, buffer, bytes_received, 0,
(struct sockaddr *)&client_addr, addr_len);
if (bytes_sent < 0) {
perror("Send error");
exit(EXIT_FAILURE);
}
}
char buffer[MAX_BUFFER_SIZE];:

This line declares a character array named buffer with a maximum size of MAX_BUFFER_SIZE. The buffer is used to store the
data received from clients.

struct sockaddr_in client_addr;:

This line declares a struct sockaddr_in named client_addr that will hold the address information of the client that sent the
data.

socklen_t addr_len = sizeof(client_addr);:

This line declares a variable addr_len of type socklen_t to store the size of the client_addr structure. It's initialized with the
size of the structure.

while (1) { ... }:

This creates an infinite loop that continually listens for incoming data from clients.
int bytes_received = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &addr_len);:

This line uses the recvfrom() function to receive data from clients.

sockfd is the socket file descriptor.

buffer is the array where the received data will be stored.

sizeof(buffer) specifies the maximum amount of data to receive (size of the buffer).

0 indicates no special flags for the receive operation.

(struct sockaddr *)&client_addr is a pointer to the client_addr structure where the client's address information will be
stored.

&addr_len is a pointer to the addr_len variable to update it with the actual size of the client's address structure.

The function returns the number of bytes received, or -1 if there's an error.


If (bytes_received < 0) { ... }:
This checks if an error occurred during the data reception.

If bytes_received is less than 0, an error occurred.


buffer[bytes_received] = '\0';:

This line adds a null-terminator at the end of the received data in the buffer, effectively converting it into a C-style string.
printf("Received from client: %s\n", buffer);:

This prints the received data to the console.

int bytes_sent = sendto(sockfd, buffer, bytes_received, 0, (struct sockaddr *)&client_addr, addr_len);:

This uses the sendto() function to send the received data (echo) back to the client.

buffer contains the data to send.

bytes_received is the size of the data in the buffer.

0 indicates no special flags for the send operation.

(struct sockaddr *)&client_addr is the client's address to which the data will be sent.
addr_len is the size of the client's address structure.
The function returns the number of bytes sent, or -1 if there's an error.
if (bytes_sent < 0) { ... }:

This checks if an error occurred during the data sending.


If bytes_sent is less than 0, an error occurred.

You might also like