You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinSocket UDP仅在Wireshark启动时正常,求排查FPGA通信问题

UDP通信仅在Wireshark启动时正常的问题排查与解决

问题背景

我有一台FPGA设备,监听1000端口的UDP报文FFFF,收到后会回复同样的UDPFFFF。在Code::Blocks中编写的C项目已添加链接器选项-lwsock32,但当前代码仅在Wireshark启动时能正常工作:此时FPGA的JTAG可收到FFFF报文,通信正常;关闭Wireshark后,JTAG仅能看到ARP报文(设备已回复),无后续UDP通信。

设备信息

  • FPGA:MAC地址34:34:45:79:34:54,IP地址192.168.150.111
  • PC:同网段IP192.168.150.5

问题现象

启动Wireshark后,可看到FPGA回复ARP报文,UDP通信完全正常;关闭Wireshark后,仅能捕获到ARP请求与回复,UDP报文无法正常传输。

Wireshark启动时的ARP回复

现有代码

#include <stdio.h>
#include <stdbool.h>
#include <windows.h>
#include <conio.h>

int main(int argc, char* argv[])
{
    SOCKET sckt;
    struct sockaddr_in sckt_addr;
    DWORD timeout;

    WSADATA WSAData;
    int rc = WSAStartup(0x202, &WSAData);
    if(rc != 0)
    {
        printf("Windows Sockets初始化失败");
        return -1;
    }

    sckt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sckt == INVALID_SOCKET)
    {
        printf("Windows Sockets初始化失败");
        return -1;
    }

    sckt_addr.sin_family = AF_INET;
    sckt_addr.sin_addr.s_addr = INADDR_ANY;
    sckt_addr.sin_port = htons(1000);

    if(bind(sckt, (LPSOCKADDR)&sckt_addr, sizeof(sckt_addr)) == SOCKET_ERROR)
    {
        printf("Windows Sockets初始化错误");
        closesocket(sckt);
        return -1;
    }

    sckt_addr.sin_addr.s_addr = inet_addr("192.168.150.111");

    char o_data[2];
    o_data[0] = o_data[1] = 0xFF;
    const int i_data_len = 7;
    char i_data[7];
    int sckt_addr_size = 32;

    while(true)
    {
        rc = sendto(sckt, o_data, 2, 0, (SOCKADDR *)&sckt_addr, sizeof(sckt_addr));

        if (rc != 2)
        {
            printf("Socket错误");
            return 1;
        }

        rc = recvfrom(sckt, i_data, i_data_len, 0, (SOCKADDR *)&sckt_addr, &sckt_addr_size);
        if (WSAGetLastError() == WSAETIMEDOUT)
        {
            printf("未收到FPGA响应");
            continue;
        }
        else
        {
            if (((unsigned char)i_data[0] << 8) + (unsigned char)i_data[1] == 0xFFFF)
                printf("\n\n设备回复了FFFF\n");
            else
            {
                printf("\n\n收到错误响应。");
                return 2;
            }
        }
    }

    closesocket(sckt);
    WSACleanup();

    return 0;
}

问题原因分析与解决建议

核心原因

关闭Wireshark后UDP无法通信,本质是PC的ARP缓存未正确更新FPGA的MAC地址,或者发送UDP时未触发ARP请求的完整处理流程。Wireshark启动时会开启网络混杂模式,强制刷新数据包捕获逻辑,间接触发了ARP缓存更新或数据包的正常转发。

针对性解决方法

  • 方法一:添加静态ARP条目
    以管理员权限打开Windows命令提示符,执行以下命令绑定FPGA的IP与MAC地址,避免动态ARP缓存失效:

    arp -s 192.168.150.111 34-34-45-79-34-54
    
  • 方法二:完善Socket超时设置
    现有代码未设置接收超时,且sendto后直接进入recvfrom可能导致ARP请求未完成就开始等待响应。在Socket初始化后添加超时配置:

    timeout = 1000; // 设置1秒接收超时
    setsockopt(sckt, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
    
  • 方法三:修正Socket地址逻辑
    现有代码中绑定本地端口后直接修改了同一个地址结构体,可能导致地址信息混乱。建议创建独立的目标地址结构体:

    struct sockaddr_in dest_addr;
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_addr.s_addr = inet_addr("192.168.150.111");
    dest_addr.sin_port = htons(1000);
    

    后续sendto操作使用这个独立的dest_addr结构体。

  • 方法四:检查防火墙规则
    确保Windows防火墙未拦截1000端口的UDP报文,可临时关闭防火墙测试,或在防火墙设置中添加UDP 1000端口的双向允许规则。


内容的提问来源于stack exchange,提问作者user13313191

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:56:00