1. 程式人生 > >Unity3d 封裝Socket創建簡單網絡

Unity3d 封裝Socket創建簡單網絡

字符串 位置 nac utf8 ont stat 簡單 back 線程

北京又在打雷下大雨了,學習Unity以來,越來越感興趣,情不自禁的想要學習更多知識

這次自己搭建一個Socket模塊,比較基礎,適合新手學習,詳細介紹Socket的搭建過程,同樣會把詳細過程在代碼裏進行註釋~

在搭建Socket過程中,需要創建以下幾個常用的方法:

1.創建套接字(socket)

2.綁定Ip和端口

3.監聽方法

4.接收客戶端請求的方法

5.收發消息的方法

創建SocketManger管理類

把客戶端與服務端代碼都寫在新建的SocketManger裏,並把SocketManger寫成單例,方便調用

using System.Net;
//引入套接字協議類
using System.Net.Sockets;
using System; using System.Text; public class SocketManager { #region 單例類 private static SocketManager instance; private SocketManager() { } public static SocketManager Instance { get { if (instance == null) { instance
= new SocketManager(); } return instance; } } #endregion public delegate void MyCallBack(string msg); //聲明一個委托類型,在服務器和客戶端工作的時候,會使用這個回調方法反饋當前交互的具體情況

服務端代碼

#region 服務器代碼
    /* 創建服務器
     * 等待客戶端的連接
     * 接受消息
     */
    Socket serverSocket;             
//創建服務器的套接字對象 MyCallBack serverCallBack; //定義一個服務器使用的回調委托對象 byte[] serverBuffer; //數據緩存區 文字,音頻,視頻,圖片... public void InitServer(MyCallBack callBack) { serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //參數(1.使用IP地址的類型 2.套接字類型,使用TCP的流式傳輸 3.使用TCP協議) serverBuffer = new byte[1024]; //初始化緩沖區的大小 serverCallBack = callBack; //綁定初始化服務器的回調方法 IPEndPoint point = new IPEndPoint(IPAddress.Any, 34567); //參數(1.地址,代表一臺電腦, 2.端口號表示一個應用) serverSocket.Bind(point); //綁定地址節點 serverSocket.Listen(10); //開始監聽, 一旦監聽成功,服務器就啟動,10代表最大監聽數量 serverCallBack("服務器啟動成功"); //服務器開始進入等待用戶連接的狀態 //開辟一條子線程實時監測是否有人連接 //一旦有客戶端連接,立馬通知主線程,通知內容會以IAsyncResult 返回,連接者的所有信息 serverSocket.BeginAccept(ServerAccept, serverSocket); } //服務器開始接收的方法 void ServerAccept(IAsyncResult ar) { serverSocket = ar.AsyncState as Socket; //拿到當前連接服務器的Socket 對象 Socket workingSocket = serverSocket.EndAccept(ar); //將當前的Socket的全部信息交給一個新的Socket處理 workingSocket.BeginReceive(serverBuffer, 0, serverBuffer.Length, SocketFlags.None,ServerReceive, workingSocket); //(數據收發緩存區,起始位置,長度,不分類型,全部接收, 接受消息之後的回調,當前Socket的狀態) serverSocket.BeginAccept(ServerAccept, serverSocket); //尾遞歸 } //服務器接收消息之後的回調方法 void ServerReceive(IAsyncResult ar) { Socket workingSorket = ar.AsyncState as Socket; int size=workingSorket.EndReceive(ar); //拿到接收到的數據一共有多少字節 string str = Encoding.UTF8.GetString(serverBuffer); //將接收到的byte數組轉換成字符串 serverCallBack("接收到了" + size + "字節"); serverCallBack(str); workingSorket.BeginReceive(serverBuffer, 0, serverBuffer.Length, SocketFlags.None, ServerReceive, workingSorket); //尾遞歸 } #endregion

客戶端代碼

#region
    Socket clientSocket;
    MyCallBack clientCallBack;
    byte[] clientBuffer;
    
    //客戶端連接服務器的方法
    public void ClientConnectServer(string ip,int port,MyCallBack callBack)
    {
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        clientBuffer = new byte[1024];
        clientCallBack = callBack;

        clientSocket.Connect(IPAddress.Parse(ip),port);      //連接服務器
        clientCallBack("連接服務器成功");
        clientSocket.BeginReceive(clientBuffer, 0, clientBuffer.Length, SocketFlags.None,ClientReceive, clientSocket);
    }

    void ClientReceive(IAsyncResult ar)
    {
        Socket WorkingSocket = ar.AsyncState as Socket;
        int size=WorkingSocket.EndReceive(ar);   //接收多少字節
        string msg= Encoding.UTF8.GetString(clientBuffer);
        clientCallBack("接收了"+size+"字節");
        clientCallBack(msg);
        clientSocket.BeginReceive(clientBuffer, size, clientBuffer.Length, SocketFlags.None, ClientReceive, WorkingSocket);
    }

    //客戶端發送消息的方法
    public void ClientSendMsg(string msg)
    {
        byte[] buffer= Encoding.UTF8.GetBytes(msg);
        clientSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, SendCallBack, clientSocket);
    }
    void SendCallBack(IAsyncResult ar)
    {
        Socket workingSocket = ar.AsyncState as Socket;
        workingSocket.EndSend(ar);
        clientCallBack("發送完成");
    }

#endregion

簡單的Socket搭建完成,但是有一點小Bug,服務器進入等待用戶連接狀態後,會開辟子線程實時檢測,沒有關閉這條線程,因此在搭建服務器的腳本,可以在Start方法裏寫一個方法,在程序退出時關閉這條線程! 這個方法在關閉程序時自動調用

private void OnApplicationQuit()
    {
        serverSocket.Shutdown(SocketShutdown.Both);
        serverSocket.Close();
    }

簡單的Socket搭建完了,當然這只是非常基礎的Socket傳遞,在實際使用中,還要考慮很多問題,比如Socket的沾包, 閉包,需要進一步處理

Unity3d 封裝Socket創建簡單網絡