【问题标题】:Trying to receive incoming UDP packets, empty buffer尝试接收传入的 UDP 数据包,清空缓冲区
【发布时间】:2017-06-30 08:20:43
【问题描述】:

我正在尝试使用 Wireshark 读取这些传入的 UDP 数据包:

我正在使用下一个代码:

    struct sockaddr_in si_other;
struct sockaddr_in remaddr;     /* remote address */
int  slen = sizeof(remaddr);

int s, recvlen;
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;

//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
    printf("Failed. Error Code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}
printf("Initialised.\n");


//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) //IPPROTO_UDP
{
    printf("socket() failed with error code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}

//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);

if (bind(s, (struct sockaddr *)&si_other, sizeof(si_other)) < 0) {
    perror("bind failed");
    return 0;
}

u_long nMode = 1; // 1: NON-BLOCKING
if (ioctlsocket(s, FIONBIO, &nMode) == SOCKET_ERROR)
{
    closesocket(s);
    WSACleanup();
    return 0;
}
//start communication
while (1)
{

    printf("waiting on port %d\n", PORT);

    if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
    {
        printf("recvfrom() failed with error code : %d", WSAGetLastError());
        exit(EXIT_FAILURE);
    }

    printf("Done");
    puts(buf);
}

我绑定的地址是192.168.1.1,端口是1234。

WSAGetLastError 给出的输出是空缓冲区错误:10035

我尝试断开防火墙、防病毒软件...我以管理员身份运行程序,但没有帮助。

为什么缓冲区是空的?我清楚地看到有数据包来了,什么可能阻止传入数据到套接字?

【问题讨论】:

  • 为什么非阻塞?
  • 因为非阻塞我能够读取错误并看到缓冲区是空的,否则程序会在 recvfrom 函数上停止......
  • 但是如果它是非阻塞的,调用可能会返回,因为还没有可用的数据。错误是什么——EAGAINEWOULDBLOCK
  • 你电脑的IP是多少?通常 .1 将是网关或路由器。
  • IP 192.168.1.1 在 IP 配置中显示为网关。也是接收包裹的那个(请参见上面的wireshark图片)...我尝试了INADDR_ANY,但没有帮助。

标签: c++ udp


【解决方案1】:

WSAGetLastError() 给出的输出是空缓冲区错误:10035

不,不是。 10035 是WSAEWOULDBLOCK。这意味着该操作将在阻塞模式下阻塞,即在您调用 recvfrom() 的那一刻没有数据可以接收。

我绑定的地址是192.168.1.1

IP 192.168.1.1 显示为网关

这两种说法相互矛盾。如果是网关,则为外部 IP 地址,如果为外部 IP 地址,则无法绑定。

我尝试了 INADDR_ANY,但没有帮助

不足为奇。如果您不是 192.168.1.1,您将无法收到它的消息。不清楚你为什么会这样想。

【讨论】:

    【解决方案2】:

    正如@EJP 提到的10035 是WSAEWOULDBLOCK,即没有数据准备好。原因是接收方是 192.168.1.1,这是您网关的 IP 地址,因此不是本地 IP。在这种情况下,您将无法正常接收数据包。

    您可以使用 UDP 嗅探器(例如,使用 libpcap)接收这些数据包,即使它们不是为您准备的。

    【讨论】:

    • 非常感谢 Jonas 澄清了为什么我无法收到这些包裹。谢谢你的链接,我去看看。
    • @joe 不客气。如果您需要进一步的帮助,请告诉我,例如,使用 libpcap 或编写自己的数据包捕获函数。如果它解决了您的问题,请接受(并可能投票)答案。
    【解决方案3】:

    感谢您的回答,他们为我指明了正确的方向。我现在已经让程序工作了,我能够接收传入的 UDP 数据包。

    解决方案是“嗅探”这些 UDP 数据包,winsock 允许在绑定后使用 WSAIoctl 函数,在我的情况下,将下一个代码添加到上述程序(在绑定函数之后):

    if (WSAIoctl(s, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD)&si_other, 0, 0) == SOCKET_ERROR)
    {
        printf("WSAIoctl() failed.\n");
        return 1;
    }
    

    我希望可以帮助其他有类似问题的人。

    【讨论】:

    • 解决方案是不绑定到外部 IP 地址。这个词是包,不是包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 2021-03-16
    • 2021-12-14
    相关资源
    最近更新 更多