I have simple MCU network what support only ARP, broadcast and unicast UDP/IP protocols and I am connecting to MCU directly without PC network (point-to-point).
In C# I have two UDP sockets - sender and listener. Listener bound to end point (listening port 60001).
But my program can work only if running Wireshark. Without Wireshark it can send only broadcast packets, but not receive.
MCU realise ARP protocol (and I tried static IP in Windows too. Command arp -s). I tried switch off Windows 10 firewall and antivirus, run program as administator and nothing. Only if I am running Wireshark my C# program receive packets.
IP header checksum is correct - I enabled checking in Wireshark. Udp checksum = 0 (PC also don't calculate the checksum)
C# code:
public void UdpConnect() {
udpSender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpListener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpListener.Bind(new IPEndPoint(IPAddress.Any, 60001));
// MCU send data to dstIP = PC_IP and dstPort = 60001
}
int Send() {
byte[] dgram = tx_buf.ToArray();
int n = udpSender.SendTo(dgram, SocketFlags.DontRoute, new IPEndPoint(IPAddress.Parse("192.168.0.200"), 60000));
// PC send data to MCU IP 192.168.0.200 and dstPort = 60000
Debug.WriteLine("Send " + n + " bytes");
return n;
}
byte[] Receive(int timeout_ms = 3000) {
byte[] data = new byte[1518];
int byteCount = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
do {
if (udpListener.Available != 0) {
Debug.WriteLine("Available: " + udpListener.Available);
byteCount = udpListener.Receive(data, data.Length, SocketFlags.None);
Debug.WriteLine("Received UDP packet length: " + byteCount);
}
else
Thread.Sleep(100);
} while (byteCount == 0 && sw.ElapsedMilliseconds < timeout_ms);
return byteCount == 0 ? null : data.Take(byteCount).ToArray();
}
byte[] SendReceive(int timeout_ms = 3000, int attempts = 3) {
byte[] result = null;
for (int i = 0; i < attempts; i++) {
Send();
result = Receive(timeout_ms);
if (result != null)
break;
else
Debug.WriteLine("Attempt " + (i + 1) + " failed");
}
if (result == null) {
Debug.WriteLine("UDP receiver timeout");
throw new TimeoutException();
}
return result;
}
The problem was in short ARP and UDP packets. I understood it when I connected my device to local network (Usually ethernet controller add padding automatic, but not XMOS).
Minimum size of Ethernet packets is 64 bytes (header + data + crc32). I sent ARP without padding and I sent short broadcast UDP too.
But I have problem with capture GOOSE packets and with SharpPcap library How I can grant permission for Pcap library in Windows 10 from C#?