C#多播UDP连接,BeginReceiveFrom异步调用停止调用 [英] C# Multicast UDP connection, BeginReceiveFrom async call stops to be called

查看:201
本文介绍了C#多播UDP连接,BeginReceiveFrom异步调用停止调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一篇文章,如果我做了我不应该做的事情,请提前道歉.我总是在这里搜索答案,但这次我什么也没看到我的问题.我在 C# 中有一个项目,我在其中保持连接 UDP 侦听来自数据流的多播 IP.

this is my first post, sorry in advance if I do something I shouldn't. I always search here for answer but this time I saw nothing about my problem. I have a project in C# where I keep alive a connection UDP listening a multicast IP from a data streaming.

我正在侦听的 IP 是一个多播流媒体,它从许多跟踪系统发送跟踪数据,因此我们可以假设发送方不是问题所在.它发送 1024 字节的数据包,60 fps.

The IP I'm listening is a multicast streamer that sends tracking data from many tracking systems, so we can assume the sender is not the problem. It sends like 1024 bytes packets, 60 fps.

这是从整个项目中提取的一个小示例,经过简化,据我测试,其行为方式与大项目中的相同.问题是,如果我连接到本地主机,这永远不会中断,但如果我连接到远程 IP,这或多或少会在 4 分钟内停止工作.

This is a small example extracted from the whole project, simplified and as far as I tested, behaves in the same way as in the big project. The problem is that if I connect in localhost this never break, but if I connect to remote IPs this stop working, more or less, in 4 minutes.

public class TrackingStateObject
{
    public Socket workSocket = null;
    public const int BUFFER_SIZE = 65507;
    public byte[] buffer = new byte[BUFFER_SIZE];
}

class MainClass
{
    static public string multicastServerIPAddress = "239.255.42.99";
    static public string realTrackingServerIPAddress = "161.116.27.144";
    static protected EndPoint trackingEndPoint;

    static public int dataPort = 2345;
    static protected Socket sockData = null;

    static int foo = 0;

    public static void Main (string[] args)
    {
        IPEndPoint ipep;
        TrackingStateObject so;

        IPAddress trackingIP = IPAddress.Parse(multicastServerIPAddress);
        trackingEndPoint = new IPEndPoint(trackingIP, dataPort);
        sockData = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        ipep = new IPEndPoint(IPAddress.Any, dataPort);

        try {
            sockData.Bind(ipep);
        }
        catch (Exception ex) {
            System.Console.WriteLine("[UDPClient] Exception "+ex.Message);
            return;
        }

        sockData.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(trackingIP));
        try {
            trackingIP = IPAddress.Parse(realTrackingServerIPAddress);
            trackingEndPoint = new IPEndPoint(trackingIP, dataPort);
        }
        catch(Exception ex) {
            System.Console.WriteLine("[UDPClient] Exception "+ex.Message);
            return;
        }

        so = new TrackingStateObject();
        so.workSocket = sockData;
        sockData.BeginReceiveFrom(so.buffer, 0, TrackingStateObject.BUFFER_SIZE, 0, ref trackingEndPoint, new AsyncCallback(AsyncReceiveCallback), so);

        System.Threading.Thread.Sleep (600000);
    }

    private static void AsyncReceiveCallback(IAsyncResult ar)
    {
        try {
            TrackingStateObject so = (TrackingStateObject)ar.AsyncState;
            Socket sock = so.workSocket;
            int read = sock.EndReceiveFrom(ar, ref trackingEndPoint);
            if (read > 0)
            {
                // Do things with the data
                System.Console.WriteLine("Recieved shit, " + read + " bytes, " + foo++ + " times.");
            }

            sock.BeginReceiveFrom(so.buffer, 0, TrackingStateObject.BUFFER_SIZE, SocketFlags.None, ref trackingEndPoint, new AsyncCallback(AsyncReceiveCallback), so);
        }
        catch (Exception e) {
            System.Console.WriteLine("[UDPClient] Exception AsynCallback "+e.Message);
        }
    } 
}

我调试了一段时间,据我所知,总是 sock.BeginReceiveFrom 被调用,在某个时候停止,AsyncReceiveCallback 永远不会再次执行.也许我在这里做了一些愚蠢的事情,但无论如何,我看不到它.谢谢!

I debugged for a while and as far I can see is that always sock.BeginReceiveFrom is called, stop in some point, AsyncReceiveCallback is never executed again. Perhaps I'm doing here something stupid, but in any case, I'm not able to see it. Thanks!

推荐答案

我遇到了完全相同的问题,这似乎只发生在 WiFi 接口上,而不是硬连线接口上.我发现的解决方案是始终在调用 BeginReceiveFrom() 之前设置 SocketOptionName.AddMembership 选项.

I was having exactly the same problem, which only seems to occur on WiFi interfaces, not hardwired interfaces. The solution I discovered was to always set the SocketOptionName.AddMembership option before calling BeginReceiveFrom().

在接收回调中,调用EndReceiveFrom() 后,设置多播地址的SocketOptionName.DropMembership 选项.

In the receive callback, after calling EndReceiveFrom() then set the SocketOptionName.DropMembership option for the multicast address.

然后在再次调用 BeginReceiveFrom() 之前,设置 SocketOptionName.AddMembership 选项.

Then before calling BeginReceiveFrom() again, set the SocketOptionName.AddMembership option.

不知道为什么必须为 WiFi 接口这样做,但它对我有用.

Not sure why this has to be done for WiFi interfaces, but it worked for me.

这篇关于C#多播UDP连接,BeginReceiveFrom异步调用停止调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆