recvfrom 函数被阻止

recvfrom function is blocked

我有以下两个文件

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 函数仍然在两者之间被阻塞

我解决了这个问题。原因是在我的系统中 net.core.rmem_max 的值被设置为 12KB。在这种情况下,我在很短的生命周期内发送了 MB 的数据。所以接收缓冲区很快就被填满了,UDP 忽略了缓冲区的其余部分。我使用以下命令

将 net.core.rmem_max 增加到 10MB
sysctl -w net.core.rmem_max=Value

此后该程序运行良好。