Socket通信实战

此通信是WPF与Unity3D之间的一个通信

此项目是基于WPF界面的实现。其中嵌入了Unity3D仿真。但是Unity3D与WPF的通信是不能直接进行的,有两种方法,一种是通过数据库,WPF给数据库中插入指令,Unity3D不断的遍历数据库,一旦发现有指令就进行某些操作,第二种方法是Socket通信。接下来进行对Socket通信的讲解。

发生端(WPF)

class SocketServer
    {
        //私有成员
        private static byte[] result = new byte[1024];
        private int myProt = 500;   //端口  
        static Socket serverSocket;
        static Socket clientSocket;

        Thread myThread;
        static Thread receiveThread;

        //属性

        public int port { get; set; }
        //方法

        static SocketServer socketServer = null;
        public static SocketServer GetInstance()
        {
            if(socketServer == null)
            {
                socketServer = new SocketServer();
                socketServer.StartServer();
            }

            return socketServer;
        }

        SocketServer()
        {

        }
        void StartServer()
        {
            //服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(ip, myProt));  //绑定IP地址:端口  
            serverSocket.Listen(10);    //设定最多10个排队连接请求  

            Debug.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());

            //通过Clientsoket发送数据  
            myThread = new Thread(ListenClientConnect);
            myThread.Start();

        }


        internal void QuitServer()
        {

            if (serverSocket != null)
                serverSocket.Close();

            if (clientSocket != null)
                clientSocket.Close();

            if(myThread != null)
                myThread.Abort();

            if(receiveThread != null)
                receiveThread.Abort();


        }


        internal void SendMessage(string msg)
        {
            if(clientSocket != null && clientSocket.Connected)
            clientSocket.Send(Encoding.ASCII.GetBytes(msg));
        }



        /// <summary>  
        /// 监听客户端连接  
        /// </summary>  
        private static void ListenClientConnect()
        {
            while (true)
            {
                try
                {
                    clientSocket = serverSocket.Accept();
                    clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
                    receiveThread = new Thread(ReceiveMessage);
                    receiveThread.Start(clientSocket);
                }
                catch (Exception)
                {

                }

            }
        }

        /// <summary>  
        /// 接收消息  
        /// </summary>  
        /// <param name="clientSocket"></param>  
        private static void ReceiveMessage(object clientSocket)
        {
            Socket myClientSocket = (Socket)clientSocket;
            while (true)
            {
                try
                {
                    //通过clientSocket接收数据  
                    int receiveNumber = myClientSocket.Receive(result);
                    Debug.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
                }
                catch (Exception ex)
                {
                    try
                    {
                        Debug.WriteLine(ex.Message);
                        myClientSocket.Shutdown(SocketShutdown.Both);
                        myClientSocket.Close();
                        break;
                    }
                    catch (Exception)
                    {
                    }

                }
            }
        }

        public void CloseClient()
        {
            if (clientSocket != null && clientSocket.Connected)
            {
                clientSocket.Close();
                clientSocket = null;
            }
        }
    }

 发送程序

 public partial class MainWindow : Window
    {

        SocketServer socketServer = null;
        public MainWindow()
        {
            InitializeComponent();

            socketServer = SocketServer.GetInstance();
        }


        
        public void SendMessage(string message)
        {
            socketServer.SendMessage(message);
        }

            
   
        public void CloseWindow()
        {

            socketServer.QuitServer();
            CloseScene();
            Close();
        }

        public void CloseScene()
        {
            socketServer.CloseClient();
            UnityControl.closeUnity3dExe();
            CloseTabControl("三维仿真场景");
        }
    }

接收端(Unity3D)

using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System;
using System.Collections.Generic;

public class SocketCommand : MonoBehaviour
{
    const int portNo = 500;
    private TcpClient _client;
    byte[] data;

    string Error_Message;

    List<string> messages = new List<string>();

    float checkTime = 0.1f;
    void Start()
    {
        try
        {
            this._client = new TcpClient();
            this._client.Connect("127.0.0.1", portNo);
            data = new byte[this._client.ReceiveBufferSize];
            //SendMessage(txtNick.Text);
            SendMessage("Unity Demo Client is Ready!");
            this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
        }
        catch (Exception ex)
        {
        }
    }

    void FixedUpdate()
    {
        checkTime -= Time.fixedDeltaTime;

        if(checkTime <= 0)
        {
            checkTime = 0.1f;

            MessageDealing();
        }
      
    }

    /// <summary>
    /// 对收到的消息的处理函数
    /// </summary>
    private void MessageDealing()
    {
        if(messages.Count > 0)
        {
            Debug.Log(messages[0]);
            Command.CommandDecoding(messages[0]);
            messages.Remove(messages[0]);
        }
    }


    public new void SendMessage(string message)
    {
        try
        {
            NetworkStream ns = this._client.GetStream();
            byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
            ns.Write(data, 0, data.Length);
            ns.Flush();
        }
        catch (Exception ex)
        {
            Error_Message = ex.Message;
            //MessageBox.Show(ex.ToString());
        }
    }
    public void ReceiveMessage(IAsyncResult ar)
    {
        try
        {
            //清空errormessage
            Error_Message = "";
            int bytesRead;
            bytesRead = this._client.GetStream().EndRead(ar);
            if (bytesRead < 1)
            {
                return;
            }
            else
            {
               // Debug.Log(System.Text.Encoding.ASCII.GetString(data, 0, bytesRead));
                string message = System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);

                messages.Add(message);
            }
            this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
        }
        catch (Exception ex)
        {
            Error_Message = ex.Message;
        }
    }

    public void CloseClient()
    {
        if(_client.Connected)
        this._client.Close();
    }
    void OnDestroy()
    {
        if (_client.Connected)
            this._client.Close();
        
    }




}