2016-03-07 78 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的值設置爲12KB。在這種情況下,我在很短的時間內發送了MB數據。所以接收緩衝區很快就被填滿了,UDP忽略了緩衝區的其餘部分。我已經使用以下命令將net.core.rmem_max增加到10MB

sysctl -w net.core.rmem_max=Value 

之後,此程序工作正常。