ESP32可正常发送UDP数据包,但Win10端.NET程序无法接收
问题:ESP32 UDP广播无法被Win10 .NET程序接收(Python可正常接收)
我正在搭建ESP32的UDP广播握手功能,让ESP32在局域网特定端口广播数据包,供同网络Win10 PC上的.NET程序接收并完成握手。目前已通过Wireshark及PC上的Python脚本确认ESP32能正常广播和接收数据包,但.NET程序无法识别来自ESP32的数据包;不过该.NET程序可接收本地另一.NET测试程序的广播(含127.0.0.1与192.168.1.255)。经初步排查Windows防火墙无阻碍,求指点排查方向。
排查方向
- 开启.NET程序的广播接收权限:Python socket默认支持广播接收,但.NET的
UdpClient默认可能关闭了该功能。在初始化UdpClient后添加以下代码:udpClient.EnableBroadcast = true; - 修正ESP32的广播地址计算:当前手动将IP最后一段设为255的方式仅适用于子网掩码为255.255.255.0的场景,改用系统提供的正确广播地址:
IPAddress broadcastIP = WiFi.broadcastIP(); - 调整.NET的远程端点配置:代码中
remoteEndPoint指定了固定端口12345,但ESP32发送广播的源端口并非固定为该值,修改为允许任意远程端口:IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - 指定.NET程序绑定的网卡:若PC存在多网卡(有线/无线),.NET可能绑定到了非目标局域网的网卡,尝试绑定到具体的局域网IP:
UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("你的PC局域网IP"), port)); - 统一数据包发送方式:ESP32改用字节数组直接发送,避免字符串转换可能的编码问题:
const char* message = "Discovery request from ESP32"; udp.beginPacket(broadcastIP, port); udp.write((const uint8_t*)message, strlen(message)); udp.endPacket(); - 检查Windows UDP监听状态:用命令行确认.NET程序是否正确监听目标端口:
netsh interface ipv4 show udpconnections
相关代码
ESP32固件代码(VSCode PlatformIO Arduino框架)
#include <Arduino.h> #include <WiFiManager.h> #include <WiFiUdp.h> #define BAUDRATE 115200 //UDP WiFiUDP udp; // UDP object const unsigned int port = 12345; // Port for UDP communication bool discovered = false; // Timing variables for sending broadcast packets unsigned long lastBroadcastTime = 0; unsigned long broadcastInterval = 2000; // Interval between broadcasts (ms) void handshakeBroadcast() { IPAddress broadcastIP = WiFi.localIP(); broadcastIP[3] = 255; // Set the last octet to 255 for broadcast Serial.print("Broadcast Address: "); Serial.println(broadcastIP); String message = "Discovery request from ESP32"; udp.beginPacket(broadcastIP, port); udp.print(message.c_str()); udp.endPacket(); if (udp.endPacket() == 1) { Serial.println("Packet sent successfully"); } else { Serial.println("Error sending packet"); } } void receiveUDP() { // Check for incoming UDP messages char incomingPacket[255]; int packetSize = udp.parsePacket(); if (packetSize) { int len = udp.read(incomingPacket, 255); if (len > 0) { incomingPacket[len] = 0; // Null-terminate the string } Serial.printf("Received UDP packet from %s:%d\n", udp.remoteIP().toString().c_str(), udp.remotePort()); Serial.printf("Packet contents: %s\n", incomingPacket); // Respond to the sender udp.beginPacket(udp.remoteIP(), udp.remotePort()); udp.print("Hello from ESP32!"); udp.endPacket(); } } void loop() { // Check for incoming UDP messages receiveUDP(); //if Pc client not discovered Boradcast Handshake unsigned long currentMillis = millis(); // Non-blocking UDP broadcast sending if (currentMillis - lastBroadcastTime >= broadcastInterval) { handshakeBroadcast(); lastBroadcastTime = currentMillis; // Update last broadcast time } } void setup() { Serial.begin(115200); //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm; bool res; res = wm.autoConnect("ESP32-Thing","12345678"); // password protected ap MIN 8 CHARACTERS if(!res) { Serial.println("Failed to connect"); // ESP.restart(); } else { // WiFi connected Serial.println("Wifi connected."); Serial.print("IP: "); Serial.println(WiFi.localIP()); Serial.print("Subnet mask: "); Serial.println(WiFi.subnetMask()); // Start UDP if (udp.begin(port)) { Serial.printf("UDP listener started on port: %d\n", port); } else { Serial.println("Failed to start UDP listener"); } } }
Win10 PC .NET程序代码
using System; using System.Net; using System.Net.Sockets; using System.Text; class UdpBroadcastListener { static void Main(string[] args) { int port = 12345; // Port to listen on IPAddress ANY = IPAddress.Parse("0.0.0.0"); UdpClient udpClient = new UdpClient(port); IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, port); // Listen on all interfaces Console.WriteLine($"Listening for broadcasts on port {port}..."); while (true) { try { byte[] receivedBytes = udpClient.Receive(ref remoteEndPoint); string receivedMessage = Encoding.UTF8.GetString(receivedBytes); Console.WriteLine($"Received packet from {remoteEndPoint} with message: {receivedMessage}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } } }
可正常接收的Python脚本
import socket # Configuration UDP_IP = "0.0.0.0" # Listen on all interfaces UDP_PORT = 12345 # Port to listen on # Create the UDP socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Bind the socket to the specified IP and port sock.bind((UDP_IP, UDP_PORT)) print(f"Listening for UDP packets on {UDP_IP}:{UDP_PORT}...") try: while True: # Receive data from the socket (buffer size of 1024 bytes) data, addr = sock.recvfrom(1024) print(f"Received message: {data.decode('utf-8')} from {addr}") except KeyboardInterrupt: print("\nExiting...") finally: sock.close()
内容的提问来源于stack exchange,提问作者boyeVR
相关产品推荐
相关产品推荐

