2012-01-27 1 views
1

У меня есть следующий код: libevC/libev: программа закрывается, когда событие срабатывает

#include <ev.h> 
#include <stdio.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/un.h> 
#include <netinet/in.h> 

ev_io stdin_watcher; 

static void cb(EV_P_ ev_io *w, int revents){ 
     puts ("hello"); 

     //read file here - suggestion due to Ioan 
     #define BUF_LEN 10 
     char buf[BUF_LEN]; 
     memset(buf,0,BUF_LEN); 
     int byte_read; 
     while((byte_read = recv(w->fd,buf,BUF_LEN-1,0)) > 0) { 
       printf("len: %i: %s",byte_read,buf); 
       memset(buf,0,BUF_LEN); 
     } 


     if(-1 == byte_read && EAGAIN != errno) { 
      perror("recv"); 
     } 
     close(w->fd); 

     //ev_io_stop (EV_A_ w); 
     //ev_unloop (EV_A_ EVUNLOOP_ALL); 
} 


int main (void){ 
     struct ev_loop *loop = ev_default_loop (0); 
     int len; 

     int sd; 
     sd=socket(AF_UNIX,SOCK_STREAM,0); 

     struct sockaddr_un address; 
     //memset(&address,0,sizeof(address)); 
     address.sun_family=AF_UNIX; 
     strcpy(address.sun_path,"/tmp/mysocket"); 
     unlink(address.sun_path); 
     len=strlen(address.sun_path)+sizeof(address.sun_family); 

     int x=bind(sd,(struct sockaddr*)&address,sizeof(address)); 
     printf("%d\n",x); 
     listen(sd,5); 

     ev_io_init(&stdin_watcher,cb,sd,EV_READ); 
     ev_io_start(loop,&stdin_watcher); 

     ev_loop (loop, 0); 

     // unloop was called, so exit 
     return 0; 
} 

Все работает нормально (почти). Скомпилируйте: gcc file.c -lev и запустите ./a.out. Затем напишите в гнездо, которое ./a.out слушает: echo "gobblydeegook" | nc -U /tmp/mysocket.

Hello появляется на консоли, как ожидалось.

Но программа вызывает событие, а затем продолжает печатать «привет» ad-infinitum! Я хочу, чтобы он продолжал отслеживать этот unix-сокет для записи. Как это сделать?

ответ

2

Событие вызывается, когда в соке есть данные. Поскольку вы не удаляете данные из сокета, просто печатая «привет», событие снова вызывается для обработки данных.

+0

Mmm. Это очень интересное спасибо. Я попытался прочитать данные (см. Обновленное сообщение, но я продолжаю получать ошибку «recv: Invalid argument». – Eamorr

+0

libev также вызывает одно и то же событие для ошибок в сокете, например, когда он закрыт. Поскольку вы закрываете сокет, событие вызывается еще раз, и в этот момент вы пытаетесь вернуться к закрытому сокету. – Ioan

+0

oh right ... Я думаю, что понимаю вас. Вы знаете какой-либо способ противодействовать этому? – Eamorr