问题描述
寻求建议/指点。我有一组可以接收 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 (将#修改为@)