未收到 Windows 10 UDP 较大的数据报?

问题描述

寻求建议/指点。我有一组可以接收 UDP 数据报的函数。一切正常,与数字混音器连接,每秒发送和接收 100 个数据报。虽然大多数数据报都在 100 字节以下,但有些更大,并且接收高达约 4kB 的数据报工作正常,但高于此的任何数据都只是......未收到,没有错误,没有报告 recvfrom() 函数而不是 select() 调用它/当我使用非阻塞调用时。下面是一个小测试程序,它可以毫无问题地接收对应于 message=1 的数据报(这是一个接近 2kB 的数据报),但是在发送 message=2 后请求更大的数据报(大约 20kB)时会挂起。注意:我系统地验证了操作系统中的最大缓冲区大小系统地为 64kB 或更多。我尝试使用 Windows、ubuntu 18.04 甚至 Mac……结果相同,但挂起相同。 Windows 系统上的 Wireshark 显示所有字节都由 NIC 接收(24383 字节)。尝试使用和不使用防火墙。

程序(没什么特别的……):

/*
 * cudp.c
 *
 *  Created on: Dec 24,2020
 *      Author: Patrick-Gilles Maillot
 *  Simple udp client
 */
#include<stdio.h>       //printf
#include<string.h>      //memset
#include<stdlib.h>      //exit(0);
#include<windows.h>

#define BUFLEN 32768            //Max length of buffer
char    buf[BUFLEN];

void die(char *s) {
    perror(s);
    exit(1);
}

int main(void) {
    struct sockaddr_in  Wip;
    struct sockaddr*    Wip_addr = (struct sockaddr *)&Wip;
    int                 Wip_len = sizeof(Wip);  // length of addresses

    int                 Wsocket,len;
    char                message[32];
    char*               mess;
    WSADATA             wsa;
    char                Wip_str[32] = {"192.168.1.71"};

    char mess_1[32] = {"/io/in/LCL\0\0,s\0\0*\0\0\0"};  // results in a 2kB datagram
    char mess_2[32] = {"/io/in\0\0,s\0\0*\0\0\0"};      // results in a 20kB datagram


    if (WSAStartup (MAKEWORD(2,2),&wsa) != 0) {
            printf ("Failed. Error Code : %d",WSAGetLastError());
            exit (EXIT_FAILURE);
    }

    if ( (Wsocket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) == -1) {
        die("socket");
    }
    int iVal = 128000;
    int iSize = sizeof(iVal);
    len = setsockopt(Wsocket,SOL_SOCKET,SO_RCVBUF,(char *) &iVal,iSize);
    printf("ret code: %d,buffer size = %d\n",len,iVal);

    len = getsockopt(Wsocket,(char *)&iVal,&iSize);
    printf("buffer size = %d\n",iVal);

//  iVal = 10000;
//  len = setsockopt(Wsocket,SO_RCVTIMEO,iSize);
//  printf("ret code: %d,iVal);
//
//  len = getsockopt(Wsocket,&iSize);
//  printf("timeout = %d\n",iVal);

    memset (&Wip,sizeof(Wip));                  // Clear struct
    memset((char *) &Wip,sizeof(Wip));
    Wip.sin_family = AF_INET;
    Wip.sin_port = htons(atoi("2223"));
    Wip.sin_addr.s_addr = inet_addr(Wip_str);


    while(1) {
        //request what message to send (1 or 2)
        printf("Enter message : ");
        gets(message);
        if (message[0] == '1') {
            mess = mess_1;
            len = 20;
        } else if (message[0] == '2') {
            mess = mess_2;
            len = 16;
        } else {
            return 0;
        }

        //send the selected message
        if ((len = sendto(Wsocket,mess,Wip_addr,Wip_len)) == -1) {
            die("sendto()");
        }
        //receive a reply and print it
        //clear the buffer by filling null,it might have prevIoUsly received data
        memset(buf,'\0',BUFLEN);
        //try to receive some data,this is a blocking call; if blocked... just Ctrl-c !
        if ((len = recvfrom(Wsocket,buf,BUFLEN,0)) == -1) {
            die("recvfrom()");
        }
        printf("len: %i: ",len);
        for (int i = 0; i < len; i++) {
            if (buf[i] < 32 || buf[i] == 255 || buf[i] == 127) printf("~");
            else                                               printf("%c",buf[i]);
        }
    }
    return 0;
}

有没有人看到/遇到过类似的问题/限制?并且能够找到解决办法?或者它就在我的眼睛下面,但它是什么?

谢谢 -帕特里克

PS:我知道 TCP 更好等等等等。我在这里没有选择。服务器是硬件系统。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)