none
为什么udpClient广播后无法接受数据了? RRS feed

  • 问题

  • 各位大大:

    最近在做一个项目,需要用udp发送广播255.255.255.255到端口10000,然后局域网中的设备就会反回一个数据包到发送时的端口,由于不同的udpclient不能绑定同一个端口,所以我用了同一个udpClient发送和接收数据,但是却无法接受数据,数据是发送了的,我用网路岗抓包看到了的。

    麻烦帮我看看是什么问题,谢谢!

    public partial class search_tool : Form
        {
            //取随机端口
            static Random rd = new Random();
            static int port = rd.Next(10300,50300);
            public Thread receiveDUPMessageThread;
            UdpClient udpClient = new UdpClient(port);
    
            public search_tool()
            {
                InitializeComponent();
            }
    
           
    
            //搜索摄像机
            private void buttonSearchCamera_Click(object sender, EventArgs e)
            {
                //发送搜索摄像机包
                byte[] searchCameraMessage = { 0,0,0,1 };
                sendUDPMessageByMultipleWithByte(0,searchCameraMessage);
            }
    
            //发数据
            public void sendUDPMessageNoPort(Byte[] message)
            {
                try
                {
                    udpClient.Connect(IPAddress.Parse("255.255.255.255"), 10000);
                    udpClient.Send(message, message.Length);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }
    
    
            //拼2个字节数组
            public byte[] combain2ByteArray(byte[] a, byte[] b)
            {
                byte[] c = new byte[a.Length+b.Length];
    
                a.CopyTo(c, 0);
                b.CopyTo(c, a.Length);
                return c;
            }
    
            //传入操作码和正文,发送UDP数据包
            public void sendUDPMessageByMultipleWithByte(short operateCodeShort,byte[] cententMessage)
            {
                byte[] head = System.Text.Encoding.ASCII.GetBytes("MO_I");
                byte[] operteCode = BitConverter.GetBytes(operateCodeShort);
                byte[] baoLiu1 = { 0x00 };
                byte[] baoliu2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                int messageLengthInt = cententMessage.Length;
                byte[] messageLength = BitConverter.GetBytes(messageLengthInt);
                byte[] baoliu3 = { 0x00, 0x00, 0x00, 0x00 };
    
                byte[] a1 = combain2ByteArray(head, operteCode);
                byte[] a2 = combain2ByteArray(a1, baoLiu1);
                byte[] a3 = combain2ByteArray(a2, baoliu2);
                byte[] a4 = combain2ByteArray(a3, messageLength);
                byte[] a5 = combain2ByteArray(a4, baoliu3);
                byte[] message = combain2ByteArray(a5, cententMessage);
                sendUDPMessageNoPort(message);
            }
    
            //监听函数
            public void receiveUDPMessage()
            {
                while (true)
                {
                    try
                    {
                        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any,0);
                        Byte[] receiveByte = udpClient.Receive(ref RemoteIpEndPoint);
                        string returnData = Encoding.ASCII.GetString(receiveByte);
                        MessageBox.Show("Message" + returnData);
                        MessageBox.Show("This message was sent from" + RemoteIpEndPoint.Address.ToString() + " on their port number " + RemoteIpEndPoint.Port.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                }
            }
    
            private void search_tool_Load(object sender, EventArgs e)
            {
                receiveDUPMessageThread = new Thread(new ThreadStart(receiveUDPMessage));
                receiveDUPMessageThread.Start();
            }
    
            private void search_tool_FormClosing(object sender, FormClosingEventArgs e)
            {
                udpClient.Close();
                receiveDUPMessageThread.Abort();
            }

    2012年11月7日 15:11

答案

  • dear

    你可参考下列接收写法

    http://www.dotblogs.com.tw/yc421206/archive/2012/10/12/76442.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    • 已标记为答案 liuyu_yuan 2012年11月8日 13:25
    2012年11月8日 4:31
  • 没办法 不用udpclient 改用socket就可以了

    namespace TENVIS_Search_Tool
    {
    
        public partial class search_tool : Form
        {
            //取随机端口
            static Random rd = new Random();
            static int port = rd.Next(10300,50300);
            //定义监听线程和udp套接字
            public Thread receiveUDPMessageThread;
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, port);
            Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    
            public search_tool()
            {
                InitializeComponent();
            }
    
            //搜索摄像机按钮
            private void buttonSearchCamera_Click(object sender, EventArgs e)
            {
                //发送搜索摄像机包
                byte[] searchCameraMessage = { 0,0,0,1 };
                sendUDPMessageByMultipleWithByte(0,searchCameraMessage);
            }
    
            //发数据
            public void sendUDPMessageNoPort(Byte[] message)
            {
                try
                {
                    //C#中发送广播消息的过程如下,注意要调用SetSockOption函数,不然要抛出异常:
                    udpSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 1); 
                    udpSocket.SendTo(message, message.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 10000));
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
    
            }
    
            //拼2个字节数组
            public byte[] combain2ByteArray(byte[] a, byte[] b)
            {
                byte[] c = new byte[a.Length+b.Length];
    
                a.CopyTo(c, 0);
                b.CopyTo(c, a.Length);
                return c;
            }
    
            //传入操作码和正文,发送UDP数据包
            public void sendUDPMessageByMultipleWithByte(short operateCodeShort,byte[] cententMessage)
            {
                byte[] head = System.Text.Encoding.ASCII.GetBytes("MO_I");
                byte[] operteCode = BitConverter.GetBytes(operateCodeShort);
                byte[] baoLiu1 = { 0x00 };
                byte[] baoliu2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                int messageLengthInt = cententMessage.Length;
                byte[] messageLength = BitConverter.GetBytes(messageLengthInt);
                byte[] baoliu3 = { 0x00, 0x00, 0x00, 0x00 };
    
                byte[] a1 = combain2ByteArray(head, operteCode);
                byte[] a2 = combain2ByteArray(a1, baoLiu1);
                byte[] a3 = combain2ByteArray(a2, baoliu2);
                byte[] a4 = combain2ByteArray(a3, messageLength);
                byte[] a5 = combain2ByteArray(a4, baoliu3);
                byte[] message = combain2ByteArray(a5, cententMessage);
                sendUDPMessageNoPort(message);
            }
    
            //监听函数
            public void receiveUDPMessage()
            {
                while (true)
                {
                    try
                    {
                        int recv;
                        byte[] data = new byte[1024]; 
                        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                        EndPoint Remote = (EndPoint)(sender);
                        recv = udpSocket.ReceiveFrom(data, ref Remote);
                        MessageBox.Show(Encoding.ASCII.GetString(data, 0, recv) + "from:" + Remote.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                }
            }
    
            //软件初始化
            private void search_tool_Load(object sender, EventArgs e)
            {
                udpSocket.Bind(ip);
                receiveUDPMessageThread = new Thread(new ThreadStart(receiveUDPMessage));
                receiveUDPMessageThread.Start();
            }
    
            //软件退出
            private void search_tool_FormClosing(object sender, FormClosingEventArgs e)
            {
                udpSocket.Close();
                receiveUDPMessageThread.Abort();
            }
        }
    }
    

    2012年11月8日 13:26

全部回复

  • 看你的code,應該有參考MSDN例子吧,我仔細看了一下MSDN Library的例子,他是先把UdpClient 用 Connect 連接到 server端,跟著才呼叫 Send 和 Receive。

    而你的code中,是從search_tool_Load中另起一個thread去呼叫UdpClient.Receive,這樣子不能確定它已連上server,建議你加Connect到receiveUDPMessage中

    http://msdn.microsoft.com/zh-tw/library/system.net.sockets.udpclient.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2

    public void receiveUDPMessage()
            {
    		UdpClient udpClientB = new UdpClient(port);
    		udpClientB.Connect(IPAddress.Parse("255.255.255.255"), 10000);
                while (true)
                {
                    try
                    {
                        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any,0);
                        Byte[] receiveByte = udpClientB.Receive(ref RemoteIpEndPoint);
                        string returnData = Encoding.ASCII.GetString(receiveByte);
                        MessageBox.Show("Message" + returnData);
                        MessageBox.Show("This message was sent from" + RemoteIpEndPoint.Address.ToString() + " on their port number " + RemoteIpEndPoint.Port.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                }
            }


    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for VB.NET since 2003
    My MSMVP Blog

    2012年11月8日 2:37
  • 谢谢你的回复,这样是不行的,因为你这样会2个udpclient绑定一个udp端口了。

    报错:”通常每个套接字地址(协议/网络地址/端口)只允许使用一次。“

    我一开始就是像你这样写的,就发现了这个问题才改成的用同一个udpclient。


    2012年11月8日 3:30
  • 那就改為跑前確認一下它有連結沒有。注意,你也要在sendUDPMessageNoPort中加進if ....Active()的測試

    public void receiveUDPMessage()
    {
       if (!udpClient.Active())
       {
       udpClient.Connect(IPAddress.Parse("255.255.255.255"), 10000);
       }
       while (true)
          {
             try
             {
                 IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any,0);
                 Byte[] receiveByte = udpClientB.Receive(ref RemoteIpEndPoint);
                 string returnData = Encoding.ASCII.GetString(receiveByte);
                 MessageBox.Show("Message" + returnData);
                 MessageBox.Show("This message was sent from" + RemoteIpEndPoint.Address.ToString() + " on their port number " + RemoteIpEndPoint.Port.ToString());
             }
             catch (Exception e)
             {
                Console.WriteLine(e.ToString());
             }
        }
    }


    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for VB.NET since 2003
    My MSMVP Blog

    2012年11月8日 3:42
  • dear

    你可参考下列接收写法

    http://www.dotblogs.com.tw/yc421206/archive/2012/10/12/76442.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    • 已标记为答案 liuyu_yuan 2012年11月8日 13:25
    2012年11月8日 4:31
  • 不知道为什么不能用该属性

    我试试看下面大哥的方法 不用udpclient

    2012年11月8日 5:15
  • 没办法 不用udpclient 改用socket就可以了

    namespace TENVIS_Search_Tool
    {
    
        public partial class search_tool : Form
        {
            //取随机端口
            static Random rd = new Random();
            static int port = rd.Next(10300,50300);
            //定义监听线程和udp套接字
            public Thread receiveUDPMessageThread;
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, port);
            Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    
            public search_tool()
            {
                InitializeComponent();
            }
    
            //搜索摄像机按钮
            private void buttonSearchCamera_Click(object sender, EventArgs e)
            {
                //发送搜索摄像机包
                byte[] searchCameraMessage = { 0,0,0,1 };
                sendUDPMessageByMultipleWithByte(0,searchCameraMessage);
            }
    
            //发数据
            public void sendUDPMessageNoPort(Byte[] message)
            {
                try
                {
                    //C#中发送广播消息的过程如下,注意要调用SetSockOption函数,不然要抛出异常:
                    udpSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 1); 
                    udpSocket.SendTo(message, message.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 10000));
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
    
            }
    
            //拼2个字节数组
            public byte[] combain2ByteArray(byte[] a, byte[] b)
            {
                byte[] c = new byte[a.Length+b.Length];
    
                a.CopyTo(c, 0);
                b.CopyTo(c, a.Length);
                return c;
            }
    
            //传入操作码和正文,发送UDP数据包
            public void sendUDPMessageByMultipleWithByte(short operateCodeShort,byte[] cententMessage)
            {
                byte[] head = System.Text.Encoding.ASCII.GetBytes("MO_I");
                byte[] operteCode = BitConverter.GetBytes(operateCodeShort);
                byte[] baoLiu1 = { 0x00 };
                byte[] baoliu2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                int messageLengthInt = cententMessage.Length;
                byte[] messageLength = BitConverter.GetBytes(messageLengthInt);
                byte[] baoliu3 = { 0x00, 0x00, 0x00, 0x00 };
    
                byte[] a1 = combain2ByteArray(head, operteCode);
                byte[] a2 = combain2ByteArray(a1, baoLiu1);
                byte[] a3 = combain2ByteArray(a2, baoliu2);
                byte[] a4 = combain2ByteArray(a3, messageLength);
                byte[] a5 = combain2ByteArray(a4, baoliu3);
                byte[] message = combain2ByteArray(a5, cententMessage);
                sendUDPMessageNoPort(message);
            }
    
            //监听函数
            public void receiveUDPMessage()
            {
                while (true)
                {
                    try
                    {
                        int recv;
                        byte[] data = new byte[1024]; 
                        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                        EndPoint Remote = (EndPoint)(sender);
                        recv = udpSocket.ReceiveFrom(data, ref Remote);
                        MessageBox.Show(Encoding.ASCII.GetString(data, 0, recv) + "from:" + Remote.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                }
            }
    
            //软件初始化
            private void search_tool_Load(object sender, EventArgs e)
            {
                udpSocket.Bind(ip);
                receiveUDPMessageThread = new Thread(new ThreadStart(receiveUDPMessage));
                receiveUDPMessageThread.Start();
            }
    
            //软件退出
            private void search_tool_FormClosing(object sender, FormClosingEventArgs e)
            {
                udpSocket.Close();
                receiveUDPMessageThread.Abort();
            }
        }
    }
    

    2012年11月8日 13:26