Unity 簡易聊天室(基於TCP)(1)


為了准備畢業設計,學習了服務器與客戶端之間傳輸的一些簡單的知識,並跟着網絡上的教程制作了一個簡易的Unity聊天室

服務器:用C# .Net Framework寫的

結構分為:main(主函數)、Server類(用於服務器的開啟和接收客戶端連接)、Client類(接收消息和發送消息)、Message類(用於消息的解析和包裝)

 

main:

    class Program
    {

        static void Main(string[] args)
        {
            string ip = "127.0.0.1";//這個ip地址表示本機
            int port = 6688; //測試用的端口號,應該可以自己隨便寫吧
            Server server = new Server(ip, port);
            server.Start();


            Console.ReadKey();
        }

    }

 

Server:

    public class Server
    {
        private Socket serverSocket = null;
        private List<Client> clientList = new List<Client>();
        private Socket clientSocket = null;


        public Server() { }

        public Server(string ip,int port)
        {
            //創建socket,然后綁定ip地址和端口號
            //傳輸類型是流,使用的協議是Tcp
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
            serverSocket.Bind(point);
        }

        public void Start()
        {
            serverSocket.Listen(0); //開始監聽  0表示等待連接隊列的最大數
            Console.WriteLine("開始監聽");
            Console.WriteLine("等待客戶端連接");
            serverSocket.BeginAccept(AcceptCallBack, null); //等待客戶端連接,AcceptCallBack是回調,第三個參數目前還沒用過,沒去了解作用  TODO
        }

        private void AcceptCallBack(IAsyncResult ar)
        {
            clientSocket = serverSocket.EndAccept(ar);
            Console.WriteLine("一個客戶端連接");
            Client client = new Client(clientSocket,this); //當客戶端連接上后,用Client類處理消息的接收與發送
            clientList.Add(client);
            client.Start();

            serverSocket.BeginAccept(AcceptCallBack, null); //服務器繼續等待其他客戶端連接
        }

        public void Broadcast(string message) //廣播消息
        {
            foreach(Client client in clientList)
            {
                client.SendMessage(message);
            }
        }
    }

 

 

Client:

 

public class Client
    {
        private Socket clientSocket;
        private Server server;
        private Message msg = new Message();

        public Client() { }

        public Client(Socket clientSocket,Server server)
        {
            this.clientSocket = clientSocket;
            this.server = server;
        }


        public void Start()
        {
            //判斷客戶端是否被關閉
            if (clientSocket.Connected == false || clientSocket.Poll(10, SelectMode.SelectRead))
            {
                clientSocket.Close();
                return;
            }
            //等待從客戶端的消息的接收
            clientSocket.BeginReceive(msg.data, 0, msg.data.Length, SocketFlags.None, ReceiveCallBack, null);
        }


        private void ReceiveCallBack(IAsyncResult ar)
        {
            try
            {
                //需要用try catch 捕捉異常,不然出現異常服務器會終止
                //判斷客戶端是否被關閉
                if (clientSocket.Connected==false || clientSocket.Poll(10,SelectMode.SelectRead))
                {
                    clientSocket.Close();
                    return;
                }

                int len = clientSocket.EndReceive(ar);//返回的len表示接收的數據長度
                if (len == 0)//客戶端被關閉了 服務端會接收到0字節的消息
                {
                    clientSocket.Close();
                    return;
                }

                msg.Read(len, OnProessMassage);//Message類解析消息
                //Console.WriteLine("receive:" + message);

                clientSocket.BeginReceive(msg.data, 0, msg.data.Length, SocketFlags.None, ReceiveCallBack, null);
            }
            catch (Exception e)
            {
                Console.WriteLine("ReceiveCallBack:" + e);
            }
            
        }

        private void OnProessMassage(string msg)
        {
            server.Broadcast(msg);//通過服務器廣播消息
        }


        public void SendMessage(string message)
        {
            //判斷客戶端是否被關閉  發送的時候客戶端也可能被關閉
            if (clientSocket.Connected == false || clientSocket.Poll(10, SelectMode.SelectRead))
            {
                clientSocket.Close();
                return;
            }


            //MethodInfo mi = msg.GetType().GetMethod("Pack");

            clientSocket.Send(msg.Pack(message));//發送消息給客戶端
            //Console.WriteLine("send:"+message);
        }

    }

 

 

Message:

 //這里只是簡單的處理消息;解析:從byte[] ->string;發送:string->byte[]

    class Message
    {

        public byte[] data = new byte[1024];

        public void Read(int len,Action<string>OnProessMessage)
        {
            string message = Encoding.UTF8.GetString(data, 0, len);
            OnProessMessage(message);
            Array.Clear(data, 0, len);
        }


        public byte[] Pack(string msg)
        {
            byte[] dataBytes = Encoding.UTF8.GetBytes(msg);
            return dataBytes;
        }

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM