The answer was to specify:
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, Port);
instead of
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Port);
for the listening socket. At first sight this seems to prevent any firewall warnings and doesn't require any rules to be added to the firewall. But I have to do some more extensive testing to be sure this works on all Windows configurations.