zoukankan      html  css  js  c++  java
  • Unity中进程间通信——使用异步Socket

    开发Unity项目过程中,即时通信功能来完成服务器与客户端自定义的数据结构封装。

    如果要序列化和数据封装参考:Unity3D之C#用Socket传数据包

    蓝鸥3G封装的类

    客户端脚本ClientScript

    /// <summary>
    /// Client Script.
    /// Created By 蓝鸥3G 2014.08.23
    /// </summary>
    
    using UnityEngine;
    using System.Collections;
    
    public class ClientScript: MonoBehaviour {
        string msg = "";
        // Use this for initialization
    
        LOSocket client;
        void Start () {
            client = LOSocket.GetSocket(LOSocket.LOSocketType.CLIENT);
            client.InitClient ("127.0.0.1", 2222, ((string content) => {
                //收到服务器的回馈信息
            }));
        }
    
        void OnGUI() {
            msg = GUI.TextField(new Rect(0, 0, 500, 40), msg);
            if(GUI.Button(new Rect(0, 50, 100, 30), "Send"))
            {
    
                client.SendMessage (msg);
            }
        }
    } 
    

    服务器端脚本

    using UnityEngine;
    using System.Collections;
    
    public class ServerScript : MonoBehaviour {
    
        private string receive_str;
        LOSocket server;
        // Use this for initialization
        void Start () 
        {
            server = LOSocket.GetSocket(LOSocket.LOSocketType.SERVER);
            //初始化服务器
            server.InitServer((string content) => {
                receive_str = content;
            });
        }
    
        void OnGUI()
        {
            if (receive_str != null) 
            {
                GUILayout.Label (receive_str);
            }
        }
    }
    

    LOSocket框架

    using UnityEngine;
    using System.Collections;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    
    //收到消息后的委托回调
    public delegate void ReceiveCallBack(string content);
    
    public class LOSocket{
    
        //可以创建的Socket端口类型
        public enum LOSocketType 
        {
            CLIENT = 0,
            SERVER = 1,
        }
        #region --------取消构造器
        private LOSocket()
        {
        }
            
        #endregion
        
        #region --------公共代码
        //通过静态方法获取不同的端口类型
        public static LOSocket GetSocket(LOSocket.LOSocketType type)
        {
            LOSocket socket = null;
    
    
            switch (type) {
            case LOSocketType.CLIENT:
                {
                    //创建一个新的客户端
                    socket = new LOSocket ();
                    break;
                }
            case LOSocketType.SERVER:
                {
                    //获取服务端
                    socket = GetServer ();
                    break;
                }
            }
    
            return socket;
        }
    
        #endregion
        #region --------客户端部分代码
        private Socket clientSocket;
    
        //声明客户端收到服务端返回消息后的回调委托函数
        private ReceiveCallBack clientReceiveCallBack;
        //用来存储服务端返回的消息数据
        byte[] Buffer = new byte[1024];
    
        //初始化客户端Socket信息
        public void InitClient(string ip,int port,ReceiveCallBack ccb)
        {
            this.clientReceiveCallBack = ccb;
            this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
            IPAddress address = IPAddress.Parse (ip);
            IPEndPoint ep = new IPEndPoint (address, port);
    
            this.clientSocket.Connect(ep);
            //开始异步等待接收服务端消息
            this.clientSocket.BeginReceive (Buffer, 0, Buffer.Length, SocketFlags.None, new System.AsyncCallback(ReceiveFromServer), this.clientSocket);
        }
    
        //收到服务端返回消息后的回调函数
        void ReceiveFromServer(System.IAsyncResult ar)
        {
            //获取当前正在工作的Socket对象
            Socket worker = ar.AsyncState as Socket;
            int ByteRead=0;
            try
            {
                //接收完毕消息后的字节数
                ByteRead = worker.EndReceive(ar);
            }
            catch (System.Exception ex)
            {
                this.clientReceiveCallBack (ex.ToString ());
            }
            if (ByteRead > 0)
            {
                string Content = Encoding.Default.GetString (Buffer);
                //通过回调函数将消息返回给调用者
                this.clientReceiveCallBack (Content);
            }
            //继续异步等待接受服务器的返回消息
            worker.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new System.AsyncCallback(ReceiveFromServer), worker);
        }
    
        //客户端主动发送消息
        public void SendMessage(string message)
        {
            if (message == null)
                return;
    
            message += "
    ";
            byte[] sendData = Encoding.UTF8.GetBytes (message);
    
            //异步发送消息请求
            clientSocket.BeginSend (sendData, 0, sendData.Length, SocketFlags.None, new System.AsyncCallback (SendToServer), clientSocket);
        }
        //发送消息结束的回调函数
        void SendToServer(System.IAsyncResult ar)
        {
            Socket worker = ar.AsyncState as Socket;
            worker.EndSend (ar);
        }
    
        #endregion
    
    
        #region -------服务器部分代码
        //服务器端收到消息的存储空间
        byte[] ReceiveBuffer = new byte[1024];
        //服务器收到消息后的回调委托
        private ReceiveCallBack callback;
    
        //单例模式  
        private static LOSocket serverSocket;  
        private static LOSocket GetServer() {  
            if (serverSocket == null) {  
                serverSocket = new LOSocket();  
            }  
            return serverSocket;  
        }  
    
        //初始化服务器信息
        public void InitServer(ReceiveCallBack cb) {
            this.callback = cb;
            // 1.
            Socket server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 2.
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 2222);
            // 3.
            server_socket.Bind(endPoint);
            // 4.
            server_socket.Listen(10);
            // 5.开始异步等待客户端的请求链接
            server_socket.BeginAccept (new System.AsyncCallback (Accept), server_socket);
    
            this.callback ("开启服务器" + endPoint.ToString());
        }
    
        //接受到客户端的链接请求后的回调函数
        void Accept(System.IAsyncResult ar){
            //获取正在工作的Socket对象 
            Socket socket = ar.AsyncState as Socket;  
            //存储异步操作的信息,以及用户自定义的数据  
            Socket worker = socket.EndAccept(ar);  
    
            SocketError error;
    
            //开始异步接收客户端发送消息内容
            worker.BeginReceive (ReceiveBuffer, 0, ReceiveBuffer.Length, SocketFlags.None, new System.AsyncCallback (Receive), worker);
            //继续异步等待新的客户端链接请求
            socket.BeginAccept(new System.AsyncCallback(Accept), socket);  
    
        }
        //服务端收到客户端的消息后的回调函数
        void Receive(System.IAsyncResult ar)
        {
            //获取正在工作的Socket对象
            Socket worker = ar.AsyncState as Socket;
            int ByteRead=0;
            try
            {
                ByteRead = worker.EndReceive(ar);
            }
            catch (System.Exception ex)
            {
                this.callback (ex.ToString ());
            }
            if (ByteRead > 0)
            {
                string Content = Encoding.Default.GetString (ReceiveBuffer);
                this.callback (Content);
            }
            //继续异步等待客户端的发送消息请求
            worker.BeginReceive(ReceiveBuffer, 0, ReceiveBuffer.Length, SocketFlags.None, new System.AsyncCallback(Receive), worker);
        }
        #endregion
    }
    

    #python客户端测试代码

    #! /usr/env/bin python  
    #codinf=utf-8  
    import socket  
    import time  
      
    def Client():  
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        sock.connect(('', 8000))#链接服务器  
        while 1:  
            print 'enter something:',  
            ent = raw_input()  
            if ent == '':  
                break  
            sock.send(ent)#发送数据给服务器  
            time.sleep(1)  
            data = sock.recv(1024)#接收服务器发过来到数据  
            print 'echo=>',data  
        sock.close()  
      
    if __name__ == '__main__':  
        Client()   

    python服务器端测试代码

    #! /usr/env/bin python  
    #coding=utf-8  
    import socket  
      
    #Server  
    def Server():  
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        sock.bind(('localhost', 8000))  
        sock.listen(5)#监听,最大链接数  
        while 1:  
            connection, address = sock.accept()#开始接受请求,进入等待阻塞状态,直到有链接到达  
            while 1:  
                data = connection.recv(1024)#接收客户端发过来的数据  
                if not data:  
                    break  
                print data,address  
                connection.send(data)#发送数据到客户端,即上面到connection  
            connection.close()  
      
      
      
    if __name__ == '__main__':  
        Server()  
    

    注意,这里没有对服务器的连接关闭,自己可以加上:sock.close()  

      

      

      

     

  • 相关阅读:
    WF4.0 Beta1 自定义跟踪
    WF4.0 Beta1 流程设计器与Activity Designer
    新版本工作流平台的 (二) 权限算法(组织结构部分)
    WF4.0 Beta1 WorkflowInvoker
    WF4.0 基础篇 (十) Collection 集合操作
    WF4.0 基础篇 (十五) TransactionScope 事物容器
    WF4.0 基础篇 (六) 数据的传递 Arguments 参数
    WF4B1 的Procedural Activity 之InvokeMethod , InvokeMethod<T> 使用
    WF4.0 Beta1 异常处理
    WF4.0 Beta1 变量 Variables
  • 原文地址:https://www.cnblogs.com/eniac1946/p/7569641.html
Copyright © 2011-2022 走看看