Unityテクニカルブログ-ProtoBufプロトコルに基づくネットワーク転送(中)

4937 ワード

Unityバージョン:5.3
使用言語:C#
前に書く
ProtoBufはGoogle社が発売したバイナリシーケンス化ツールで、データのネットワーク転送に適しています.Socketに基づいて時々通信を実現するには,データボンドパケットの符号化と復号化処理が不可欠である.
実装機能:
   1.  ProtoBuf     
   2.  Socket      
   3.         

2.UnityではSocketを使用して時々通信を実現
通信が実現すべき機能:
  • 1.サーバは、複数のクライアント
  • を常時傍受することができる.
  • 2.サーバは、あるクライアントメッセージ
  • を時々傍受することができる.
  • 3.サーバは、あるクライアントに時々メッセージ
  • を送信することができる.
    まずクライアントオブジェクトを定義する必要があります
    using System;
    using System.Net.Sockets;
    
    /// 
    ///        
    /// 
    public class NetUserToken {
        //      Socket
        public Socket socket;
        //        
        public byte[] buffer;
    
        public NetUserToken()
        {
            buffer = new byte[1024];
        }
    
        /// 
        ///     
        /// 
        /// Data.
        public void Receive(byte[] data)
        {
            UnityEngine.Debug.Log("     !");
        }
    
        /// 
        ///     
                /// 
        /// Data.
        public void Send(byte[] data)
        {       
    
        }
    }
    

    サーバコードを実装
    using System.Collections;
    using System.Collections.Generic;
    using System.Net;
    using System;
    using System.Net.Sockets;
    
    public class NetServer{
        //    
        public static readonly NetServer Instance = new NetServer();
        //  tcp   
        private Socket server;
        private int maxClient = 10;
        //    
        private int port = 35353;
        //   
        private Stack pools;
        private NetServer()
        {
            //   socket
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Bind(new IPEndPoint(IPAddress.Any, port));
    
        }
    
        //     
        public void Start()
        {
            server.Listen(maxClient);
            UnityEngine.Debug.Log("Server OK!");
            //          
            pools = new Stack(maxClient);
            for(int i = 0; i < maxClient; i++)
            {
                NetUserToken usertoken = new NetUserToken();
                pools.Push(usertoken);
            }
            //         , BeginAccept             ,              
            server.BeginAccept (AsyncAccept, null);
        }
    
        //    ,                  
        private void AsyncAccept(IAsyncResult result)
        {
            try {
                //    ,        
                Socket client = server.EndAccept(result);
                UnityEngine.Debug.Log("      ");
                //       
                NetUserToken userToken = pools.Pop();
                userToken.socket = client;
                //       ,         
                BeginReceive(userToken);
    
                //   ,               
                server.BeginAccept(AsyncAccept, null);
            } catch (Exception ex) {
                UnityEngine.Debug.Log(ex.ToString());
            }
        }
    
        //      
        private void BeginReceive(NetUserToken userToken)
        {
            try {
                //    
                userToken.socket.BeginReceive(userToken.buffer, 0, userToken.buffer.Length, SocketFlags.None,
                                              EndReceive, userToken);
            } catch (Exception ex) {
                UnityEngine.Debug.Log(ex.ToString());
            }
        }
    
        //            
        private void EndReceive(IAsyncResult result)
        {
            try {
                //     
                NetUserToken userToken = result.AsyncState as NetUserToken;
                //       
                int len = userToken.socket.EndReceive(result);
                if(len > 0)
                {   
                    byte[] data = new byte[len];
                    Buffer.BlockCopy(userToken.buffer, 0, data, 0, len);
                    //      
                    userToken.Receive(data);
                    //   ,         
                    BeginReceive(userToken);
                }
    
            } catch (Exception ex) {
                UnityEngine.Debug.Log(ex.ToString());
            }
        }
    }
    

    Unityでサーバを起動し、C#コンソールを使用してクライアント接続、メッセージ送信操作をシミュレートします.テストOKで、Unityでは常にメッセージを監視することができます.
    using UnityEngine;
    using System.Collections;
    
    public class CreateServer : MonoBehaviour {
    
        void StartServer () {
            NetServer.Instance.Start();
        }
    
    }
    
    //C#     
    
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Text;
    
    namespace Temp
    {
        class MainClass
        {
            public static void Main (string[] args)
            {
                TcpClient tc = new TcpClient();
                IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 35353);
                tc.Connect(ip);
    
                if(tc.Connected)
                {
                    while(true)
                    {
    
                        string msg = Console.ReadLine();
                        byte[] result = Encoding.UTF8.GetBytes(msg);
                        tc.GetStream().Write(result, 0, result.Length);
                    }
                }
                Console.ReadLine();
            }
        }
    }
    

    最後に書く
     #         ,         ,       。