2009-12-05 4 views
1

J'ai ce code qui utilise epoll et il a un problème. Quand je lance, il donne une sortie: serveur socket() est OK ... serveur bind() est OK ... accepter: Invalid argumentaccepter/epoll problème

Je suis en cours d'exécution sur Ubuntu linux, système mis à jour, à la fois en tant qu'utilisateur limité et la racine quel est le problème avec l'entrée à accepter? Que devrais-je changer?

struct epoll_event ev, events[MAX_EVENTS]; 
    struct sockaddr_in serveraddr; 
    int listen_sock, conn_sock, nfds, epollfd; 
    int yes = 1; 

    /* Set up listening socket, 'listen_sock' (socket(), 
    bind(), listen()) */ 

if((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
{ 
    perror("Server-socket() error lol!"); 
    //just exit lol! 
    exit(1); 
} 
printf("Server-socket() is OK...\n"); 
//"address already in use" error message 
/*if(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) 
{ 
    perror("Server-setsockopt() error lol!"); 
    exit(1); 
} 
printf("Server-setsockopt() is OK...\n");*/ 
// bind 
serveraddr.sin_family = AF_INET; 
serveraddr.sin_addr.s_addr = INADDR_ANY; 
serveraddr.sin_port = htons(PORT); 
memset(&(serveraddr.sin_zero), '\0', 8); 
if(bind(listen_sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) 
{ 
    perror("Server-bind() error lol!"); 
    exit(1); 
} 
printf("Server-bind() is OK...\n"); 

epollfd = epoll_create(MAX_EVENTS); 
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 (;;) { 
    nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1); 
    if (nfds == -1) { 
    perror("epoll_pwait"); 
    exit(EXIT_FAILURE); 
    } 

    for (int n = 0; n < nfds; ++n) { 
    if (events[n].data.fd == listen_sock) { 
     struct sockaddr_in clientaddr; 
     socklen_t addrlen = sizeof(clientaddr); 
     cout <<listen_sock <<'\n' <<epollfd <<'\n'; 
     conn_sock = accept(listen_sock, (struct sockaddr *) &clientaddr, &addrlen); 
     if (conn_sock == -1) { 
     perror("accept"); 
     exit(EXIT_FAILURE); 
     } 
     fcntl(conn_sock, F_SETFL, fcntl(conn_sock, F_GETFD, 0)|O_NONBLOCK); 
     ev.events = EPOLLIN | EPOLLET; 
     ev.data.fd = conn_sock; 
     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, 
     &ev) == -1) { 
     perror("epoll_ctl: conn_sock"); 
     exit(EXIT_FAILURE); 
     } 
    } else { 
     printf("%d\n", events[n].data.fd); 
    } 
    } 
} 

Répondre

-1

J'ai créé votre source et j'ai obtenu les mêmes résultats. Le epoll_wait retourne immédiatement même s'il n'y a rien à accepter.

Il semble être le cas que l'utilisation epoll_wait au lieu de écouter est pas pris en charge le comportement.

7

Vous avez oublié d'appeler écouter() après bind():

listen(listen_sock, 5); 
+0

C'est exact. Ajouter "écouter" après l'appel initial à "epoll_ctl" fonctionne. – themis

+0

from accept (2) Page de manuel: EINVAL Socket n'écoute pas les connexions, ou addrlen est invalide (par exemple, est négatif). – user666412