简体   繁体   中英

UDP epoll detects the data only from single port

I was trying to implementing a program to understand the real working of UDP epoll. I have done the code as below. This is working for a single socket. But when I tried with multiple socket (say 4 sockets for 10000, 10001, 10002, 10003), it detects the data only on last socket (here 4th, ie 10003). Do any one look my code and let me know what is the issue here?

#include <sys/types.h> 
#include <sys/socket.h>
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <sys/epoll.h>

#define MAX_EVENTS 20
#define MAXLINE    1024

int get_new_socket(int port)
{
    int sockfd;
    struct sockaddr_in servaddr;

    if ((sockfd = socket(PF_INET, SOCK_DGRAM /*|SOCK_NONBLOCK|SOCK_CLOEXEC*/, IPPROTO_UDP)) < 0 ) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

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

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

    if (bind(sockfd, (const struct sockaddr *)&servaddr,
            sizeof(servaddr)) < 0 )
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    return sockfd;
}

void recv_send_data(int sockfd)
{
    char buffer[MAXLINE]; 
    char *hello = "Hello from server"; 
    struct sockaddr_in cliaddr; 
    int ret;

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

    int len = sizeof(cliaddr), n = 17; 
    n = recvfrom(sockfd, (char *)buffer, MAXLINE, 0, (struct sockaddr *)&cliaddr, &len);
    perror("recvfrom");
    buffer[n] = '\0'; 
    printf("[%d]Client : %s\n", n, buffer);
    ret = sendto(sockfd, (const char *)hello, 17, 0, (const struct sockaddr *)&cliaddr, len); 

    printf("sent back to client.[%d]\n", ret);
}

int main(int argc, char *argv[]) {
    struct epoll_event ev, events[MAX_EVENTS];
    int listen_sock, nfds, epollfd, n;
    int start_port = 10000;

    for(n = start_port; n < start_port + 4; n++) {
        listen_sock = get_new_socket(n);
        printf("Created socket[%d] for port %d\n", listen_sock, n);
        epollfd = epoll_create1(0);
        if (epollfd == -1) {
            perror("epoll_create");
            exit(EXIT_FAILURE);
        }

        ev.events = EPOLLIN;
        ev.data.fd = listen_sock;
        if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
            perror("epoll_ctl: listen_sock");
            exit(EXIT_FAILURE);
        }
    }

    for (;;) {
        printf("Waiting on epoll\n");
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            perror("epoll_pwait");
            exit(EXIT_FAILURE);
        }

        printf("EPOLL wait over; processing...\n");
        for (n = 0; n < nfds; ++n) {
            if (events[n].data.fd == listen_sock) {
                printf("Data received on: %d, listen_sock: %d\n", events[n].data.fd, listen_sock);
                recv_send_data(listen_sock);
            }
        }
        sleep(1);
    }
}

Why are you creating epoll for each and every FD. You need to create epoll only one using epoll_create and use for all fd.

epollfd = epoll_create1(0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM