1. 程式人生 > >UDP區域網廣播實現CS房間列表

UDP區域網廣播實現CS房間列表

/*--------------------------------------------------
 * // 檔案功能描述:UDP廣播IP地址。實現類似CS的區域網房間列表
 ---------------------------------------------------*/

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Threading;
using System.Collections.Generic;
using System.Net;
using System.Text;
using UnityEngine.UI;
using System.Net.Sockets;
using System;
using System.Net.NetworkInformation;

public class JuYuWangBroadCast : MonoBehaviour {

    #region
    private int bcPort = 7788;//廣播埠

    private string curIp;//當前PC的Ip

    private Thread sendThread;
    private Thread rcvThread;

    private bool isSendTdStart = false;
    private bool isRcvTdStart = false;

    public List<string> serverList = new List<string>();//接收到的伺服器列表
    public List<int> ipTimeList = new List<int>();//Ip計時列表,通過IP該值可知該ip是否有效
    public List<int> unValIpList = new List<int>();//無效的伺服器索引

    private int curServerCount;
    private bool isServerCountChange = false;

    string msg = "";//發出去的資訊
    string rcvMsg = "";
    string showStr = "";

    //public Text msgText;
    public bool isServer = false;

    private UdpClient client1;
    private UdpClient client2;

    private StringBuilder sBuilder;
    private UFE ufe;

    private string tempIp;

    private float delTime = 2;
    private float delTimer = 0;

    void Start()
    {
        Init();
    }

     void Update()
    {
        delTimer += Time.deltaTime;
        if (delTimer > delTime)
        {
            delTimer = 0;
            //清理無效的Ip
            ClearUnValidIp();
        }
    }

    //清理無效的Ip
    private void ClearUnValidIp()
    {
        //for (int i = 0; i < ipTimeList.Count; i++)
        //{
        //    if (ipTimeList[i] < valTimer - serverList.Count*900 || ipTimeList[i] > valTimer + serverList.Count * 900)
        //    {
        //        unValIpList.Add(i);
        //    }
        //}

        for (int i = 0; i < ipTimeList.Count; i++)
        {
            if (ipTimeList[i] == 0)
            {
                unValIpList.Add(i);
            }
            else
            {
                ipTimeList[i] = 0;
            }
        }

        for (int j = unValIpList.Count - 1; j >= 0; j--)
        {
            Debug.Log("存在無效ip");

            serverList.RemoveAt(unValIpList[j]);
            ipTimeList.RemoveAt(unValIpList[j]);
        }
        unValIpList.Clear();
 
    }


    private void ClearServerList()
    {
        serverList.Clear();
    }

    //得到區域網內所有的伺服器列表
    public List<string> GetServerList()
    {
        return serverList;
    }
   
    private void Init()
    {
        sBuilder = new StringBuilder();
        ufe = Camera.main.GetComponent<UFE>();

        System.Net.IPHostEntry myEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
        curIp = myEntry.AddressList[0].ToString();

        serverList.Clear();
        isServerCountChange = false;

        //監聽埠看是否有PC發信息過來
        if (null == rcvThread)
        {
            isRcvTdStart = true;

            rcvThread = new Thread(new ThreadStart(RcvMsg));
            rcvThread.IsBackground = true;
            rcvThread.Start();
        }

        //向內網其他人發信息
        if (null == sendThread)
        {
            isSendTdStart = true;

            sendThread = new Thread(new ThreadStart(SendMsg));
            sendThread.IsBackground = true;
            sendThread.Start();
        }
    }


    int timerr = 0;
    private void RcvMsg()
    {

        client1 = new UdpClient(new IPEndPoint(IPAddress.Any, bcPort));
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);

        while (isRcvTdStart)
        {
            //Debug.Log("1");

            byte[] bytes = client1.Receive(ref endPoint);
            rcvMsg = Encoding.Default.GetString(bytes);

            if (string.IsNullOrEmpty(rcvMsg))
            {
               // Debug.Log("接收到的資料為null");
                // msgText.text = "未收到其他主機發來的訊息";
            }
            else
            {
                if (!rcvMsg.Contains("-") || rcvMsg.Contains(curIp))//收到的訊息來自其他客戶端或當前客戶端
                {

                   // Debug.Log("接收到了客戶端" + rcvMsg + "的訊息");
                    //continue;
                }
                else
                {
                    string[] rcvArray = rcvMsg.Split('-');

                    for (int i = 0; i < serverList.Count; i++)
                    {
                        if (serverList[i].StartsWith(rcvArray[1]))
                        {
                            ipTimeList[i]++;
                        }
                    }

                    //rcvMsg = rcvArray[1] + "-" + rcvArray[2];
                    sBuilder.Append(rcvArray[1]);
                    sBuilder.Append("-");
                    sBuilder.Append(rcvArray[2]);
                    rcvMsg = sBuilder.ToString();
                    sBuilder.Remove(0, sBuilder.Length);
                    if (rcvArray[0] == "S")//接收到的是伺服器的Ip
                    {
                        //Debug.Log(serverList[0]);
                        //Debug.Log(rcvMsg);
                         if (!serverList.Contains(rcvMsg))
                        {

                            serverList.Add(rcvMsg);
                            ipTimeList.Add(10);

                            if (ipTimeList.Count > serverList.Count)
                            {
                                ipTimeList.RemoveRange(serverList.Count, ipTimeList.Count - 1);
                            }
                        }
                    }
                }
            }
        }

    }
    
    int timer = 0;
    private void SendMsg()
    {
        client2 = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), bcPort);//IPAddress.Parse("255.255.255.255")  IPAddress.Any

        while (isSendTdStart)
        {
            //Debug.Log("2");

            if (isServer)
            {
                //msg = "S-" + curIp + "-1";

                sBuilder.Append("S");
                sBuilder.Append("-");
                sBuilder.Append(curIp);
                sBuilder.Append("-");
                sBuilder.Append(1);//Network.connections.Length + 1  (ufe.curNetNum).ToString()
                msg = sBuilder.ToString();
                sBuilder.Remove(0, sBuilder.Length);
            }
            else
            {
                msg = curIp;
            }
            byte[] bytes = Encoding.Default.GetBytes(msg);

            //timer++;
            //if (timer > 2000)//2000
            //{
            //    timer = 0;
                client2.Send(bytes, bytes.Length, endPoint);
            Thread.Sleep(100);
            //}
        }
    }


    public void CloseThreadBtn()
    {
        KillThread();
    }

    //關閉執行緒
    private void KillThread()
    {
        //Debug.Log("kill thread");
        isServer = false;
        client1.Close();
        client2.Close();

        if (null != sendThread)
        {
            isSendTdStart = false;
            sendThread.Abort();
        }
        if (null != rcvThread)
        {
            isRcvTdStart = false;
            rcvThread.Abort();
        }
    }

    void OnApplicationQuit()
    {
        KillThread();
    }

    void OnDestroy()
    {
        KillThread();
    }


    #endregion


}