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;
        }

    }

 

posted @ 2018-12-05 17:45  darkif  阅读(1172)  评论(0编辑  收藏  举报