Implementing UDP Broadcasting in C with epoll

UDP Broadcasting Implementation in C

The follownig example demonstraets how to create a UDP broadcast cliant in C using epoll for efficient I/O multiplexing. This client broadcasts messages to a specified network address and port, then listens for server responses.

Code Implementation


#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>

#define MAX_BUFFER 1024
#define MAX_EPOLL_EVENTS 8

int main(int argc, char *argv[]) {
    int target_port = 0;
    char *network_addr = NULL;
    int cmd_option;

    // Parse command line arguments
    while ((cmd_option = getopt(argc, argv, "p:a:")) != -1) {
        switch (cmd_option) {
            case 'p':
                target_port = atoi(optarg);
                break;
            case 'a':
                network_addr = optarg;
                break;
            default:
                fprintf(stderr, "Usage: %s [-p port] [-a broadcast_address]\n", argv[0]);
                exit(EXIT_FAILURE);
        }
    }

    // Validate required parameters
    if (target_port == 0 || network_addr == NULL) {
        fprintf(stderr, "Both port and broadcast address must be specified\n");
        exit(EXIT_FAILURE);
    }

    // Create UDP socket
    int comm_socket;
    if ((comm_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // Enable broadcast capability
    int broadcast_flag = 1;
    if (setsockopt(comm_socket, SOL_SOCKET, SO_BROADCAST, &broadcast_flag, sizeof(broadcast_flag)) < 0) {
        perror("Broadcast option setting failed");
        close(comm_socket);
        exit(EXIT_FAILURE);
    }

    // Configure server address structure
    struct sockaddr_in destination;
    memset(&destination, 0, sizeof(destination));
    destination.sin_family = AF_INET;
    destination.sin_port = htons(target_port);
    
    if (inet_pton(AF_INET, network_addr, &destination.sin_addr) <= 0) {
        perror("Invalid network address");
        close(comm_socket);
        exit(EXIT_FAILURE);
    }

    // Initialize epoll instance
    int epoll_descriptor = epoll_create1(0);
    if (epoll_descriptor < 0) {
        perror("Epoll creation failed");
        close(comm_socket);
        exit(EXIT_FAILURE);
    }

    // Add socket to epoll
    struct epoll_event epoll_instance;
    epoll_instance.events = EPOLLIN;
    epoll_instance.data.fd = comm_socket;

    if (epoll_ctl(epoll_descriptor, EPOLL_CTL_ADD, comm_socket, &epoll_instance) < 0) {
        perror("Epoll control failed");
        close(epoll_descriptor);
        close(comm_socket);
        exit(EXIT_FAILURE);
    }

    // Prepare for message sending
    char message_buffer[MAX_BUFFER];
    struct epoll_event active_events[MAX_EPOLL_EVENTS];
    
    printf("Enter message to broadcast: ");
    fflush(stdout);
    
    if (fgets(message_buffer, MAX_BUFFER, stdin) == NULL) {
        perror("Input error");
        close(epoll_descriptor);
        close(comm_socket);
        exit(EXIT_FAILURE);
    }
    
    // Remove newline character if present
    size_t message_length = strlen(message_buffer);
    if (message_length > 0 && message_buffer[message_length - 1] == '\n') {
        message_buffer[message_length - 1] = '\0';
        message_length--;
    }

    // Broadcast the message
    ssize_t bytes_sent = sendto(comm_socket, message_buffer, message_length, 0, 
                              (struct sockaddr *)&destination, sizeof(destination));
    if (bytes_sent < 0) {
        perror("Message sending failed");
        close(epoll_descriptor);
        close(comm_socket);
        exit(EXIT_FAILURE);
    }

    // Wait for server response
    while (1) {
        int event_count = epoll_wait(epoll_descriptor, active_events, MAX_EPOLL_EVENTS, -1);
        if (event_count < 0) {
            perror("Epoll wait error");
            break;
        }

        for (int i = 0; i < event_count; i++) {
            // Check for errors
            if (active_events[i].events & (EPOLLERR | EPOLLHUP) || 
                !(active_events[i].events & EPOLLIN)) {
                fprintf(stderr, "Epoll error on socket\n");
                break;
            }

            // Receive server response
            ssize_t bytes_received = recvfrom(comm_socket, message_buffer, MAX_BUFFER, 0, NULL, NULL);
            if (bytes_received < 0) {
                perror("Message receiving failed");
                break;
            }

            printf("Server response: %s\n", message_buffer);
            break;
        }
        break; // Exit after receiving first response
    }

    // Cleanup resources
    close(comm_socket);
    close(epoll_descriptor);

    return EXIT_SUCCESS;
}

Compilation and Execution

To compile this program, use the following command:

gcc -o broadcast_client broadcast_client.c

Execute the client with the target port and broadcast address:

./broadcast_client -p <port> -a <broadcast_address>

The client will prompt you to enter a message, broadcast it to the specified address, and display any response received from the server.

Tags: udp broadcasting Epoll network-programming c-language

Posted on Mon, 01 Jun 2026 16:58:26 +0000 by morph07