Unity TCP Socket的簡單使用

nity內部封裝了一個很高層次的網絡接口,不過有時候並不需要那麼複雜的功能,只是想實現簡單的TCP網絡連接,可以在unity裏面用C#寫tcp socket。

以下TCP連接是同步模式

建立兩個unity工程,編寫腳本。

服務端

using UnityEngine;
using System.Collections;
//引入庫
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class TcpServer:MonoBehaviour
{
    //以下默認都是私有的成員
    Socket serverSocket; //服務器端socket
    Socket clientSocket; //客戶端socket
    IPEndPoint ipEnd; //偵聽端口
    string recvStr; //接收的字符串
    string sendStr; //發送的字符串
    byte[] recvData=new byte[1024]; //接收的數據,必須爲字節
    byte[] sendData=new byte[1024]; //發送的數據,必須爲字節
    int recvLen; //接收的數據長度
    Thread connectThread; //連接線程

    //初始化
    void InitSocket()
    {
        //定義偵聽端口,偵聽任何IP
        ipEnd=new IPEndPoint(IPAddress.Any,5566);
        //定義套接字類型,在主線程中定義
        serverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        //連接
        serverSocket.Bind(ipEnd);
        //開始偵聽,最大10個連接
        serverSocket.Listen(10);



        //開啓一個線程連接,必須的,否則主線程卡死
        connectThread=new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }

    //連接
    void SocketConnet()
    {
        if(clientSocket!=null)
            clientSocket.Close();
        //控制檯輸出偵聽狀態
        print("Waiting for a client");
        //一旦接受連接,創建一個客戶端
        clientSocket=serverSocket.Accept();
        //獲取客戶端的IP和端口
        IPEndPoint ipEndClient=(IPEndPoint)clientSocket.RemoteEndPoint;
        //輸出客戶端的IP和端口
        print("Connect with "+ipEndClient.Address.ToString()+":"+ipEndClient.Port.ToString());
        //連接成功則發送數據
        sendStr="Welcome to my server";
        SocketSend(sendStr);
    }

    void SocketSend(string sendStr)
    {
        //清空發送緩存
        sendData=new byte[1024];
        //數據類型轉換
        sendData=Encoding.ASCII.GetBytes(sendStr);
        //發送
        clientSocket.Send(sendData,sendData.Length,SocketFlags.None);
    }

    //服務器接收
    void SocketReceive()
    {
        //連接
        SocketConnet();      
        //進入接收循環
        while(true)
        {
            //對data清零
            recvData=new byte[1024];
            //獲取收到的數據的長度
            recvLen=clientSocket.Receive(recvData);
            //如果收到的數據長度爲0,則重連並進入下一個循環
            if(recvLen==0)
            {
                SocketConnet();
                continue;
            }
            //輸出接收到的數據
            recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
            print(recvStr);
            //將接收到的數據經過處理再發送出去
            sendStr="From Server: "+recvStr;
            SocketSend(sendStr);
        }
    }

    //連接關閉
    void SocketQuit()
    {
        //先關閉客戶端
        if(clientSocket!=null)
            clientSocket.Close();
        //再關閉線程
        if(connectThread!=null)
        {
            connectThread.Interrupt();
            connectThread.Abort();
        }
        //最後關閉服務器
        serverSocket.Close();
        print("diconnect");
    }

    // Use this for initialization
    void Start()
    {
        InitSocket(); //在這裏初始化server
    }


    // Update is called once per frame
    void Update()
    {

    }

    void OnApplicationQuit()
    {
        SocketQuit();
    }
}

 

  • 創建套接字
  • 綁定套接字到ip和端口
  • 偵聽連接
  • 接收連接
  • 與客戶端收發數據
  • 返回等待另一連接
  • 斷開連接

把腳本掛到unity場景中某個物體上,比如camera,由於創建連接後有接收循環,所以要單獨開一個線程,否則主線程會卡死。

 

客戶端

  • 創建套接字
  • 向服務器發出連接請求
  • 和服務器通信
  • 斷開連接

同樣把腳本掛到場景某個物體中,創建連接和接收循環都放在新開的線程裏面,在界面上放一個文字編輯框和一個button用於給服務端發消息。

 

測試

程序實現的功能爲,當一個新的客戶端連接到服務端時,服務端控制檯輸出相關信息,並向客戶端發送初始信息,客戶端每次向服務端的信息由服務端接收後添加一段字符串再發送回來。

 

 

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