2016-03-07 5 views
0

я после двух файловфункция recvfrom блокируется

Client.c

int main(void) 
       { 
       struct sockaddr_in si_other; 
       int s, i, slen=sizeof(si_other); 
       char buf[BUFLEN]; 

       if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
        exit(-1); 

       memset((char *) &si_other, 0, sizeof(si_other)); 
       si_other.sin_family = AF_INET; 
       si_other.sin_port = htons(PORT); 
       if (inet_aton(SRV_IP, &si_other.sin_addr)==0) { 
        fprintf(stderr, "inet_aton() failed\n"); 
        exit(1); 
       } 

       for (i=0; i<NPACK; i++) { 
        printf("Sending packet %d\n", i); 
        sprintf(buf, "This is packet %d\n", i); 
        if (sendto(s, buf, BUFLEN, 0, &si_other, slen)==-1) 
        exit(1); 
       } 
       sleep(10); 
       close(s); 
       return 0; 
       } 

Server.c

int tries=0; /* Count of times sent - GLOBAL for signal-handler access */ 
    void diep(char *s) 
    { 
    perror(s); 
    exit(1); 
    } 


    void CatchAlarm(int ignored)  /* Handler for SIGALRM */ 
    { 
    tries += 1; 
    } 

    void DieWithError(char *errorMessage) 
    { 
    } 
    /* Error handling function */ 
    void *print_message_function(void *ptr) 
    { 
    char *message; 

    usleep(6200*1000); 
    message = (char *) ptr; 
    printf("%s \n", message); 
    sleep(20); 
    } 
    int main(void) 
    { 
    struct sockaddr_in si_me, si_other; 
    int s, i, slen=sizeof(si_other); 
    struct sigaction myAction;  /* For setting signal handler */ 
    const char *message1 = "Thread 1===================================="; 
    char buf[BUFLEN]; 
    pthread_t thread1, thread2; 
    pthread_create(&thread1, NULL, print_message_function, (void*) message1); 
    if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
    diep("socket"); 
    myAction.sa_handler = CatchAlarm; 
    if (sigfillset(&myAction.sa_mask) < 0) /* block everything in handler */ 
    DieWithError("sigfillset() failed"); 
    myAction.sa_flags = 0; 

    if (sigaction(SIGALRM, &myAction, 0) < 0) 
    DieWithError("sigaction() failed for SIGALRM"); 
    memset((char *) &si_me, 0, sizeof(si_me)); 
    si_me.sin_family = AF_INET; 
    si_me.sin_port = htons(PORT); 
    si_me.sin_addr.s_addr = htonl(INADDR_ANY); 
    if (bind(s, &si_me, sizeof(si_me))==-1) 
    diep("bind"); 
    alarm(TIMEOUT_SECS); 
    for (i=0; i<NPACK; i++) { 
    if (recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)==-1) 
    { 
    printf("Inside eagain %d\n",errno); 
    if(errno == EINTR) 
     { 
      alarm(TIMEOUT_SECS);  /* Set the timeout */ 
     } 
    else 
     exit(-1); 
    } 
    else 
    printf("Received packet from %s:%d\nData: %s\n\n", 
    inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf); 

    } 
    alarm(0); 

    pthread_join(thread1, NULL); 
    close(s); 
    return 0; 
    } 

Я бегу сервер первым, то клиент. В некоторых случаях сервер не может получить сообщение, отправленное моим клиентом. Хотя клиент успешно отправил его. Даже ошибка EINTR также я получаю из-за тревоги, но все же функция recvfrom блокируется между

+0

Выполнение 'print_message_fundtion()' в отдельном потоке совершенно бессмысленно. Запустите его после получения сообщения. Ваша обработка ошибок оставляет желать лучшего. Если системный вызов возвращает -1, вы должны * распечатать ошибку, * через 'perror(), strerror()' и т. Д. – EJP

+0

Вероятно, следует отметить этот вопрос C, а не C++. Получите более целенаправленные ответы. – user4581301

+0

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

ответ

1

Я решил проблему. Причина в моей системе - значение net.core.rmem_max было установлено на 12 КБ. И в этом случае я отправлял МБ данных за очень короткий промежуток времени. Таким образом, буфер приемника был вскоре заполнен, а UDP игнорировал остальную часть буфера. Я увеличил net.core.rmem_max 10Мб, используя следующую команду

sysctl -w net.core.rmem_max=Value 

После того, что эта программа работает нормально.