我有以下两个文件

客户端

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;
}

服务器
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

之后,该程序运行良好。

10-08 03:37