• 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;
            }
    
        }
  • 相关阅读:
    ADT Android Development Tools
    ADT下载地址(含各版本)
    如何在eclipse中添加android ADT
    3D MAX 人物骨骼建设
    如何绕开验证码(原理)
    二分查找 java
    Linux命令 cat命令
    Linux如何通过命令查看日志文件的某几行(中间几行或最后几行)
    Linux中显示一个文件最后几行的命令
    深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
  • 原文地址:https://www.cnblogs.com/darkif/p/10072160.html
Copyright © 2020-2023  润新知