.NET Udp 廣播

/*	Author:Wilson	Date:20200111
*/	Udp廣播工具
using System;
using LitJson;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
using System.Collections.Generic;

namespace UdpTool
{
    public class UdpManager
    {
        public UdpConfig udpConfig = new UdpConfig();

        public UdpManager()
        {
            Start();
        }

        public UdpManager(UdpConfig _udpConfig)
        {
            udpConfig = _udpConfig;
            Start();
        }

        public UdpManager(UdpConfig _udpConfig, string name)
        {
            udpConfig = _udpConfig;
            Start(name);
        }

        ~UdpManager()
        {

        }

        void Start()
        {
            if (udpConfig.udpType == UdpType.server)
            {
                UdpData.StarThread(Send);
            }
            else
            {
                UdpData.StarThread(Receive);
            }
        }
        
        void Start(string name)
        {
            if (udpConfig.udpType == UdpType.server)
            {
                UdpData.StarThread(Send);
            }
            else
            {
                UdpData.StarThread(Receive);
            }
        }

        #region Broadcast

        void Send()
        {
            Socket SendSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp);

            EndPoint SendTVep = new IPEndPoint(IPAddress.Broadcast, udpConfig.sendPort);

            SendSock.SetSocketOption(SocketOptionLevel.Socket,
            SocketOptionName.Broadcast, 1);

            string IP = "";
            IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
            for (int i = 0; i < addressList.Length; i++)
            {
                IP += addressList[i].ToString();
            }
            Debug.Log("This ip :  " + IP);

            UdpData.StartSocket(SendSock);

            while (true)
            {
                if (!string.IsNullOrEmpty(udpConfig.sendData))
                {
                    byte[] SenData = Encoding.UTF8.GetBytes(udpConfig.sendData);
                    Debug.Log("Send msg: " + udpConfig.sendData);
                    try
                    {
                        SendSock.SendTo(SenData, SendTVep);
                    }
                    catch (Exception e)
                    {
                        Debug.Log("Socket error : " + e.Message);
                    }
                }

                Thread.Sleep(udpConfig.delay);
            }
        }

        void Receive()
        {
            Socket ReceiveSock = new Socket(AddressFamily.InterNetwork,
            SocketType.Dgram, ProtocolType.Udp);

            IPEndPoint iep =
            new IPEndPoint(IPAddress.Any, udpConfig.receivePort);
            ReceiveSock.Bind(iep);
            EndPoint ReceiveEP = (EndPoint)iep;

            UdpData.StartSocket(ReceiveSock);
            byte[] ReceiveData = new byte[102400];
            while (true)
            {
                int ReceiveRecv = ReceiveSock.ReceiveFrom(ReceiveData, ReceiveData.Length, SocketFlags.None, ref ReceiveEP);
                try
                {
                    udpConfig.receiveData = Encoding.UTF8.GetString(ReceiveData, 0, ReceiveRecv);
                    Debug.Log("Receive >>> " + udpConfig.receiveData + " length: ");
                }
                catch (Exception e)
                {
                    Debug.Log("Receive Error >>>  " + e.Message);
                }
                Thread.Sleep(udpConfig.delay);
            }
        }

        #endregion
    }

    [System.Serializable]
    public class UdpConfig
    {
        public UdpType udpType;
        public UdpDevice device;
        public int sendPort = 10000;
        public Socket socket;
        public string sendData;

        public int receivePort = 10001;
        public string receiveData;
        public int delay = 100;
    }

    public class UdpData
    {
        public static Dictionary<string, Thread> ThreadPool = new Dictionary<string, Thread>();
        public static List<Socket> SocketPool = new List<Socket>();

        public static void StarThread(ThreadStart thread)
        {
            Thread _thread = new Thread(thread);
            string name = _thread.GetHashCode().ToString();
            if (ThreadPool.ContainsKey(name))
            {
                _thread.Abort();
                Debug.LogError("It was exist.");
                return;
            }
            else
            {
                _thread.IsBackground = true;
                _thread.Start();
                ThreadPool.Add(name, _thread);
            }
        }

        public static void StartSocket(Socket socket)
        {
            if (SocketPool.Contains(socket))
            {
                socket.Close();
                SocketPool.Remove(socket);
            }
            else
            {
                SocketPool.Add(socket);
                Debug.Log("Socket open: " + socket.AddressFamily);
            }
        }

        public static void CloseAll()
        {
            try
            {
                if (SocketPool.Count > 0)
                {
                    for (int i = 0; i < SocketPool.Count; i++)
                    {
                        SocketPool[i].Close();
                    }
                    SocketPool.Clear();
                }

                if (ThreadPool.Count > 0)
                {
                    foreach (KeyValuePair<string,Thread> item in ThreadPool)
                    {
                        item.Value.Abort();
                    }
                }
                Debug.Log("Close all thread.");

            }
            catch (Exception ex)
            {
                Debug.LogError(ex.Message);
            }
        }

        public static void CloseThread(string name)
        {
            try
            {
                if (ThreadPool.Count > 0)
                {
                    if (ThreadPool.ContainsKey(name))
                    {
                        ThreadPool[name].Abort();
                    }
                }
                Debug.Log("Close thread: " + name);

            }
            catch (Exception ex)
            {
                Debug.LogError(ex.Message);
            }
        }
    }

    public enum UdpType
    {
        server,
        client
    }

    public enum UdpDevice
    {
        leap,
        speech,
        tv,
        phone
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章