[英]C# UdpSocket starts receiving after send and stops receiving after a few packages
我正在嘗試通過 UdpSocket 從多播地址接收數據。 在我通過套接字發送數據之前,套接字不接收數據。 發送后,我可以收到幾個包裹,然后我必須再次發送,才能收到更多包裹。 同時從其他主機發送的包丟失。 我認為,這不是像這里這樣的防火牆問題: C# UDP Socket 直到發送數據后才接收數據,因為 whireshark 接收所有包。 有人可以解釋我這種行為嗎?
class Program
{
private static UdpClient _mdnsSocket;
private static IPEndPoint _mdnsGroup;
private static IPEndPoint _localEp;
static void Main(string[] args)
{
var interfaces = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => i.OperationalStatus == OperationalStatus.Up)
.ToArray();
for (int i = 0; i < interfaces.Length; ++i)
{
var interf = interfaces[i];
Console.WriteLine("{0}) Name: {1}", i, interf.Name);
}
Console.WriteLine();
do
{
int i;
Console.Write("Interface: ");
var line = Console.ReadLine();
if (int.TryParse(line, out i) && i < interfaces.Length)
{
var addr = interfaces[i].GetIPProperties()
.UnicastAddresses.FirstOrDefault(a => a.Address.AddressFamily == AddressFamily.InterNetwork);
if (addr != null)
{
_localEp = new IPEndPoint(addr.Address, 5353);
Console.WriteLine("Choosen IP: {0}", _localEp);
}
}
} while (_localEp == null);
_mdnsGroup = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353);
_mdnsSocket = new UdpClient();
_mdnsSocket.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_mdnsSocket.ExclusiveAddressUse = false;
_mdnsSocket.Client.Bind(_localEp);
_mdnsSocket.JoinMulticastGroup(_mdnsGroup.Address, _localEp.Address);
BeginReceive();
Console.WriteLine("1 to switch to multicast mode (default)");
Console.WriteLine("2 to switch to unicast mode");
Console.WriteLine("s for sending a message");
Console.WriteLine("ESC for exit");
ConsoleKey key;
IPEndPoint ip = _mdnsGroup;
IPEndPoint unicastip = null;
var mode = "multicast";
do
{
Console.Write("1/2/s/ESC: ");
key = Console.ReadKey().Key;
Console.WriteLine();
switch (key)
{
case ConsoleKey.D1:
ip = _mdnsGroup;
Console.WriteLine("Switched to multicast mode");
mode = "multicast";
break;
case ConsoleKey.D2:
Console.Write("Enter new IP (leave empty to use {0}):", unicastip);
var input = Console.ReadLine();
if (string.IsNullOrEmpty(input))
{
if (unicastip == null)
{
Console.WriteLine("error: no last ip!");
break;
}
ip = unicastip;
Console.WriteLine("Switched to unicast mode");
mode = "unicast";
}
else
{
unicastip = new IPEndPoint(IPAddress.Parse(input), 5353);
ip = unicastip;
Console.WriteLine("Switched to unicast mode");
mode = "unicast";
}
break;
case ConsoleKey.S:
var msg = string.Format("Hello from PC via {0}", mode);
var bytes = Encoding.ASCII.GetBytes(msg);
Console.WriteLine("Sending to {0}", ip);
_mdnsSocket.Send(bytes, bytes.Length, ip);
break;
}
} while (key != ConsoleKey.Escape);
_mdnsSocket.Close();
}
private static void BeginReceive()
{
Console.WriteLine("BeginReceive");
_mdnsSocket.BeginReceive(ReceiveCallback, _mdnsSocket);
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
var ep = new IPEndPoint(IPAddress.Any, _mdnsGroup.Port);
var data = _mdnsSocket.EndReceive(ar, ref ep);
var message = Encoding.ASCII.GetString(data);
Console.WriteLine(message);
}
finally
{
BeginReceive();
}
}
}
畢竟它似乎是一個防火牆問題。 當我明確允許端口 5353 上的傳入 UPD 時,它正在工作(為什么允許相應程序的所有傳入 UPD 流量不起作用) 。 我現在用所謂的打孔機制解釋問題中描述的行為。 當我錯了,請糾正我。
同樣的問題在這里,但防火牆沒有修復它。 我正在使用 Windows 10 PRO。
我發現了另一個不良影響:沒有收到廣播消息,但收到了直接的 IP 消息。
我發現的唯一解決方法是添加一個計時器,該計時器每 10 秒在廣播中發送一個空字節數組,因此通信保持得足夠好。 問題是總是有無用的消息傳輸到網絡,不是那么重,但遠非最佳。
關閉套接字並重新啟動也可以解決問題,但速度較慢,並且會強制 GC 運行。
我在 Unity (Mono) 和 Visual Studio 應用程序上使用相同的 UDP 類,但這種“效果”只發生在 Unity 應用程序下。 這只發生在 IPV4 套接字上,IPV6 套接字似乎永遠不會停止監聽。
我確定這是新操作系統中的某種“停止使用 IPV4 廣播”功能,因為 Windows 7 工作得很好。
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.