1. 程式人生 > >Unity使用C#實現簡單Scoket連線及服務端與客戶端通訊

Unity使用C#實現簡單Scoket連線及服務端與客戶端通訊

簡介:

網路程式設計是個很有意思的事情,偶然翻出來很久之前剛開始看Socket的時候寫的一個例項,貼出來吧

Unity中實現簡單的Socket連線,c#中提供了豐富的API,直接上程式碼。

服務端程式碼:

    Thread connectThread;//當前服務端監聽子執行緒
    public string address;//當前地址
    public int port;//當前本地埠
    TcpClient romoteClient;//遠端客戶端

    // Use this for initialization
    void Start()
    {
        connectThread = new Thread(InitServerSocket);
        connectThread.Start();
    }

    /// <summary>
    /// 例項化服務端Socket
    /// </summary>
    public void InitServerSocket()
    {
        int bufferSize = 8192;//緩衝區大小
        IPAddress ip = IPAddress.Parse(address);
        //新建TCP連線,並開啟監聽子執行緒
        TcpListener tcpListener = new TcpListener(ip, port);
        tcpListener.Start();
        Debug.Log("服務端-->客戶端完成,開啟tcp連線監聽");
        //如果有遠端客戶端連線,此時得到其物件用於通訊
        romoteClient = tcpListener.AcceptTcpClient();
        Debug.Log("客戶端連線開始 本地地址埠: " + romoteClient.Client.LocalEndPoint + "  遠端客戶端地址埠: " + romoteClient.Client.RemoteEndPoint);
        NetworkStream stream = romoteClient.GetStream();
        do
        {
            try
            {
                //獲取與客戶端連線資料
                byte[] buffer = new byte[bufferSize];
                int byteRead = stream.Read(buffer, 0, bufferSize);
                if (byteRead == 0)
                {
                    Debug.Log("客戶端斷開");
                    break;
                }
                string msg = Encoding.UTF8.GetString(buffer, 0, byteRead);
                Debug.Log("接收到客戶端的資料: " + msg + "   資料長度: " + byteRead + "位元組");

            }
            catch (Exception ex)
            {
                Debug.Log("客戶端異常: " + ex.Message);
                //客戶端出現異常或者斷開的時候,關閉執行緒防止溢位
                tcpListener.Stop();
                break;
            }
        } while (true);
    }

    /// <summary>
    /// 伺服器端根據當前連線的遠端客戶端傳送訊息
    /// </summary>
    public void SendMessageToClient()
    {
        if (romoteClient != null)
        {
            romoteClient.Client.Send(Encoding.UTF8.GetBytes("Hello Client ,This is Server!"));
        }
    }

    /// <summary>
    /// 銷燬時關閉監聽執行緒及連線
    /// </summary>
    void OnDestroy()
    {
        if (romoteClient != null)
            romoteClient.Close();
        if (connectThread != null)
            connectThread.Abort();
    }

客戶端程式碼:

    public string serverAddress;//伺服器地址
    public int port;//伺服器埠
    private TcpClient localClient;//當前tcp客戶端
    private Thread receiveThread;//接收伺服器訊息執行緒
    private byte[] resultBuffer = new byte[1024];//伺服器返回流位元組
    private string resultStr;//伺服器返回字串

    void Start()
    {
        //連線至服務端
        InitClientSocket();
    }

    /// <summary>
    /// 銷燬時操作
    /// </summary>
    private void OnDestroy()
    {
        if (localClient != null)
            localClient.Close();
        if (receiveThread != null)
            receiveThread.Abort();
    }

    /// <summary>
    /// 客戶端例項化Socket連線
    /// </summary>
    private void InitClientSocket()
    {
        localClient = new TcpClient();
        try
        {
            //當前客戶端連線的伺服器地址與遠端埠
            localClient.Connect(IPAddress.Parse(serverAddress), port);
            //開始接收伺服器訊息子執行緒
            receiveThread = new Thread(SocketReceiver);
            receiveThread.Start();
            Debug.Log("客戶端-->服務端完成,開啟接收訊息執行緒");
        }
        catch (Exception ex)
        {
            Debug.Log("客戶端連線伺服器異常: " + ex.Message);
        }
        Debug.Log("連線到伺服器 本地地址埠:" + localClient.Client.LocalEndPoint + "  遠端伺服器埠:" + localClient.Client.RemoteEndPoint);
    }

    /// <summary>
    /// 客戶端傳送訊息到伺服器
    /// </summary>
    private void SendMessageToServer()
    {
        try
        {
            string clientStr = "Hello Server, This is Client!";
            //獲取當前客戶端的流物件,然後將要傳送的字串轉化為byte[]寫入傳送
            NetworkStream stream = localClient.GetStream();
            byte[] buffer = Encoding.UTF8.GetBytes(clientStr);
            stream.Write(buffer, 0, buffer.Length);
        }
        catch (Exception ex)
        {
            Debug.Log("傳送訊息時伺服器產生異常: " + ex.Message);
        }
    }

    /// <summary>
    /// 客戶端檢測收到伺服器資訊子執行緒
    /// </summary>
    private void SocketReceiver()
    {
        if (localClient != null)
        {
            while (true)
            {
                if (localClient.Client.Connected == false)
                    break;
                //在迴圈中,
                localClient.Client.Receive(resultBuffer);
                resultStr = Encoding.UTF8.GetString(resultBuffer);
                Debug.Log("客戶端收到伺服器訊息 : " + resultStr);
            }
        }
    }

此時,面板填入服務端的地址及埠,執行服務端,再執行客戶端,客戶端點擊發送訊息,伺服器收到訊息,服務端傳送訊息後,客戶端收到訊息。本人是在兩臺機器上進行測試,Debug如下:

服務端:


客戶端:


注意事項:

1.服務端和客戶端的地址不要寫錯

2.服務端的埠確保未被佔用

3.在進行通訊的時候,要保持字串編碼格式一致

4.子執行緒的生命週期,記得銷燬,為了保證在主執行緒銷燬同時銷燬子執行緒可以使用thread.IsBackground = true