无法加入组播组c#

时间:2017-08-24 18:03:59

标签: c# sockets networking sharppcap

在我的项目中,我需要通过UDP接收视频。源的IP为224.0.0.21,Sink的IP为169.254.170.141。我通过端口3956接收视频(这是来自Wireshark的有效信息)。我使用SharpPcap接收UDP流量,但它没有加入多播的方法。我从MSDN尝试此代码,但它不起作用。

        IPAddress multicastaddress = IPAddress.Parse("224.0.0.21");
        IPEndPoint remoteep = new IPEndPoint(IPAddress.Any, 3956);
        m_ClientTarget.JoinMulticastGroup(multicastaddress, localAddr);

在我的电脑中,我有一些网络适配器,但我使用设备的IP地址,连接到源视频。源和接收器直接连接。当我在wireshark中启动监控流量时,我的程序也会收到数据包,但没有线路,它就无法做到。 我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpPcap;
using SharpPcap.LibPcap;
using SharpPcap.AirPcap;
using SharpPcap.WinPcap;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading;

namespace GVSPCapture
{
    public partial class Form1 : Form
    {

        static int frameCounter = 0;
        static byte[] pixels = new byte[1920 * 1080 * 3];
        static IPAddress fpgaAddr = IPAddress.Parse("224.0.0.21");
        static IPAddress localAddr = IPAddress.Parse("169.254.170.141");
        static MulticastOption mcastOption = new MulticastOption(fpgaAddr, localAddr);
        private static UdpClient m_ClientTarget = new UdpClient(3956);
        private static IPAddress m_GrpAddr;
        const int GroupPort = 3956;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            findDevices();
        }

        public void findDevices()
        {
            string ver = SharpPcap.Version.VersionString;

            var devices = CaptureDeviceList.Instance;

            foreach (var dev in devices)
            {
                lbxDevices.Items.Add(dev.Name + dev.Description);
            }

        }

        private void JoinVideoMulticast()
        {

            IPAddress multicastaddress = IPAddress.Parse("224.0.0.21");
            IPEndPoint remoteep = new IPEndPoint(IPAddress.Any, 3956);
            m_ClientTarget.JoinMulticastGroup(multicastaddress, IPAddress.Parse("169.254.170.141"));

            while (true)
            { }

        }

        private void startCapture(ICaptureDevice dev)
        {
            if (!dev.Started)
            {
                dev.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
                int readTimeoutMilliseconds = 1000;
                if (dev is AirPcapDevice)
                {
                    // NOTE: AirPcap devices cannot disable local capture
                    var airPcap = dev as AirPcapDevice;
                    airPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp, readTimeoutMilliseconds);
                }
                else if (dev is WinPcapDevice)
                {
                    var winPcap = dev as WinPcapDevice;

                    winPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp | SharpPcap.WinPcap.OpenFlags.NoCaptureLocal, readTimeoutMilliseconds);
                }
                else if (dev is LibPcapLiveDevice)
                {
                    var livePcapDevice = dev as LibPcapLiveDevice;
                    livePcapDevice.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
                }
                else
                {
                    throw new System.InvalidOperationException("unknown device type of " + dev.GetType().ToString());
                }

                dev.StartCapture();

                Thread recvThread = new Thread(JoinVideoMulticast);
                recvThread.Start();

            }
        }

        delegate void SetTextCallback(string text);

        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.tbxCnt.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.tbxCnt.Text = text;
            }
        }

        private void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            var time = e.Packet.Timeval.Date;
            var len = e.Packet.Data.Length;
            if (len == 572)
            {
                var tmp = e.Packet.Data;
                int packet_id = tmp[47] << 16 | tmp[48] << 8 | tmp[49];
                int startPos = (packet_id - 1) * 522;
                for (int i = 50; i < tmp.Length; i+=3)
                {
                    pixels[startPos + i + 0 - 50] = tmp[i];
                    pixels[startPos + i + 1 - 50] = tmp[i];
                    pixels[startPos + i + 2 - 50] = tmp[i];
                }
            }
            if (len == 60)
            {
                var im = CopyDataToBitmap(pixels);
                pictbFrame.Image = im;
                frameCounter += 1;
                SetText(frameCounter.ToString());
            }
        }

        public Bitmap CopyDataToBitmap(byte[] data)
        {
            GCHandle pinned = GCHandle.Alloc(data, GCHandleType.Pinned);
            IntPtr ptr = pinned.AddrOfPinnedObject();
            BitmapData dt = new BitmapData();
            dt.Scan0 = ptr;
            dt.Stride = 5760;
            dt.Width = 1920;
            dt.Height = 1080;
            dt.PixelFormat = PixelFormat.Format24bppRgb;
            Bitmap btm = new Bitmap(1920, 1080, 5760, PixelFormat.Format24bppRgb, dt.Scan0);
            return btm;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            int devNum = lbxDevices.SelectedIndex;
            if (devNum > 0)
            {
                var device = CaptureDeviceList.Instance[devNum];
                startCapture(device);
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            int devNum = lbxDevices.SelectedIndex;
            if (devNum > 0)
            {
                var device = CaptureDeviceList.Instance[devNum];
                if (device.Started)
                {
                    device.StopCapture();
                    device.Close();
                }
            }
            m_ClientTarget.DropMulticastGroup(fpgaAddr);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我用ffmpeg

测试了代码
  

ffmpeg.exe -i aa.mp4 -f mpeg udp://224.0.0.21:3956

int PORT = 3956;
string MULTICAST_IP = "224.0.0.21";


UdpClient udpClient = new UdpClient(PORT);
udpClient.JoinMulticastGroup(IPAddress.Parse(MULTICAST_IP));

var from = new IPEndPoint(0, 0);
var recvBuffer = udpClient.Receive(ref from);

答案 1 :(得分:0)

没有看到你的代码(我假设你的代码不仅仅是代码片段),很难帮助你。 接收多播数据报的客户端的基本设置类似于未经测试的代码段:

UdpClient mClient = new UdpClient(3956, AddressFamily.InterNetwork);
IPAdress groupAddress = IPAddress.Parse("224.0.0.21);
mClient.JoinMulticastGroup(groupAddress);

之后你使用mClient.Receive()...

进行接收

也许这会有帮助吗?或MSDN上的文档(https://msdn.microsoft.com/en-us/library/ekd1t784(v=vs.110).aspx)。

下进行。