Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#UdpSocket在发送后开始接收,在几个包后停止接收_C#_Udp_Multicast_Beginreceive - Fatal编程技术网

C#UdpSocket在发送后开始接收,在几个包后停止接收

C#UdpSocket在发送后开始接收,在几个包后停止接收,c#,udp,multicast,beginreceive,C#,Udp,Multicast,Beginreceive,我试图通过UdpSocket从多播地址接收数据。 在我通过套接字发送数据之前,套接字不接收数据。发送后,我可以收到几个包裹,然后我必须再次发送,才能收到更多包裹。同时从其他主机发送的包丢失。 我认为,这不是像这里这样的防火墙问题:因为whireshark接收所有包。谁能给我解释一下这种行为吗 class Program { private static UdpClient _mdnsSocket; private static IPEndPoint _mdnsGroup;

我试图通过UdpSocket从多播地址接收数据。 在我通过套接字发送数据之前,套接字不接收数据。发送后,我可以收到几个包裹,然后我必须再次发送,才能收到更多包裹。同时从其他主机发送的包丢失。 我认为,这不是像这里这样的防火墙问题:因为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();
        }
    }
}
类程序
{
专用静态UdpClient mdnsSocket;
专用静态IPEndPoint(mdnsGroup);
专用静态iEndpoint\u localEp;
静态void Main(字符串[]参数)
{
var interfaces=NetworkInterface.GetAllNetworkInterfaces()
.Where(i=>i.OperationalStatus==OperationalStatus.Up)
.ToArray();
对于(int i=0;ia.Address.AddressFamily==AddressFamily.InterNetwork);
if(addr!=null)
{
_localEp=新的IPEndPoint(地址,5353);
WriteLine(“Choosen IP:{0}”,_localEp);
}
}
}while(_localEp==null);
_mdnsGroup=新的IPEndPoint(IPAddress.Parse(“224.0.0.251”),5353);
_mdnsSocket=新的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切换到多播模式(默认)”);
Console.WriteLine(“2切换到单播模式”);
Console.WriteLine(“用于发送消息的s”);
控制台写入线(“退出ESC”);
控制台键;
IPEndPoint ip=\mdnsu组;
IPEndPoint unicastip=null;
var mode=“多播”;
做
{
控制台。写入(“1/2/s/ESC:”);
key=Console.ReadKey().key;
Console.WriteLine();
开关(钥匙)
{
案例ConsoleKey.D1:
ip=\mdnsu组;
Console.WriteLine(“切换到多播模式”);
mode=“多播”;
打破
案例ConsoleKey.D2:
Write(“输入新IP(留空以使用{0}”)”,unicastip;
var input=Console.ReadLine();
if(string.IsNullOrEmpty(输入))
{
if(unicastip==null)
{
WriteLine(“错误:没有最后一个ip!”);
打破
}
ip=unicastip;
Console.WriteLine(“切换到单播模式”);
mode=“单播”;
}
其他的
{
unicastip=newIPendpoint(IPAddress.Parse(input),5353);
ip=unicastip;
Console.WriteLine(“切换到单播模式”);
mode=“单播”;
}
打破
case ConsoleKey.S:
var msg=string.Format(“通过{0}来自PC的Hello”,模式);
var bytes=Encoding.ASCII.GetBytes(msg);
WriteLine(“发送到{0}”,ip);
_发送(字节,字节,长度,ip);
打破
}
}while(key!=ConsoleKey.Escape);
_mdnsSocket.Close();
}
私有静态void BeginReceive()
{
Console.WriteLine(“BeginReceive”);
_BeginReceive(ReceiveCallback,\u mdnsSocket);
}
私有静态void ReceiveCallback(IAsyncResult ar)
{            
尝试
{
var ep=新的IPEndPoint(IPAddress.Any,\u mdnsGroup.Port);
var data=_mdnsSocket.EndReceive(ar,ref-ep);
var message=Encoding.ASCII.GetString(数据);
控制台写入线(消息);
}
最后
{
BeginReceive();
}
}
}

毕竟,这似乎是一个防火墙问题。当我明确地在端口5353上允许传入UPD时,它正在工作(为什么允许各个程序的所有传入UPD通信都不工作)。我现在用所谓的机制来解释问题中描述的行为。当我错的时候请纠正我。

这里也有同样的问题,但防火墙并没有解决它。我正在使用Windows10Pro

我还发现了另一个不希望出现的效果:广播的消息没有被接收到,但是直接的IP消息被接收到

我发现的唯一解决方法是添加一个计时器,每10秒在广播中发送一个空字节数组,这样通信就可以保持得足够好。 问题是,总是有无用的消息传输到网络上,虽然不是很重,但远远不是最优的

关闭套接字并再次启动也解决了问题,但速度较慢,并强制GC运行

我在Unity(Mono)和Visual Studio应用程序上使用相同的UDP类,但这种“效果”仅在Unity应用程序下发生。 这仅在IPV4套接字、IPV6套接字上发生