Unity Socket之TcpClient讲解


本篇讲解的socket虽然是基础,但是socket应用的思路体现了





还有某些服务器是  单线程 事件驱动 非阻塞I/O 的,这个图我就不化了,IO抛给底层的操作系统来做


服务器一般用一个字典来管理其服务的所有客户端,这个字典的key值可以是一个唯一的账号,也可以是本篇文章的客户端的IP地址,还有可能是接收到的客户端的socket


大并发通常的框架如下:

java的Mina,Netty框架

c++ Windows操作系统的的完成端口模型

c#的 Windows操作系统的SAEA模型




下面是一个专门用于封装一个客户端的数据封装类

    class ChatClient
    {
        public static Hashtable ALLClients = new Hashtable(); // 客户列表

        private TcpClient _client;  // 客户端实体
        public string _clientIP;   // 客户端IP
        private string _clientNick; // 客户端昵称

        private byte[] data;        // 消息数据

        private bool ReceiveNick = true;

        public ChatClient(TcpClient client)
        {
            this._client = client;

            this._clientIP = client.Client.RemoteEndPoint.ToString();

            // 把当前客户端实例添加到客户列表当中
            ALLClients.Add(this._clientIP, this);

            data = new byte[this._client.ReceiveBufferSize];

            // 从服务端获取消息
            client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);  //这个就是在做异步处理
        }

        // 从客戶端获取消息
        public void ReceiveMessage(IAsyncResult ar)
        {
           
            int bytesRead;

            try
            {
            //    lock (this._client.GetStream())
            //    {
                    bytesRead = this._client.GetStream().EndRead(ar);
                    Console.Write("bytesRead"+bytesRead);
             //   }
                    Console.Write(bytesRead);
                if (bytesRead < 1)
                {
                    ALLClients.Remove(this._clientIP);

                    Broadcast(this._clientNick + "has left the chat");  //Broadcast这个函数是向所有的客户端广播消息

                    return;
                }
                else
                {
                    string messageReceived = System.Text.Encoding.UTF8.GetString(data, 0, bytesRead);

                    if (ReceiveNick) 
                    {
                        this._clientNick = messageReceived;

                        Broadcast(this._clientNick + " has joined the chat. huan yin ni");//Broadcast这个函数是向所有的客户端广播消息

                        //this.sendMessage("hello");

                        ReceiveNick = false;
                    }
                    else
                    {
                        Broadcast(this._clientNick + ">" + messageReceived);

                    }
                }

                lock (this._client.GetStream())
                {
                    this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
                }
            }
               catch (Exception ex)
               {
                ALLClients.Remove(this._clientIP);

                Broadcast(this._clientNick + " has left the chat.");
           
               
               }
        }

        // 向客戶端发送消息
        public void sendMessage(string message)
        {
            try
            {
                System.Net.Sockets.NetworkStream ns;

                lock (this._client.GetStream())
                {
                    ns = this._client.GetStream();
                }

                // 对信息进行编码
                byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(message);

                ns.Write(bytesToSend, 0, bytesToSend.Length);
                ns.Flush();
            }
            catch (Exception ex)
            {

            }
        }

        // 向客户端广播消息
        public void Broadcast(string message)
        {
            Console.WriteLine(message);

            foreach (DictionaryEntry c in ALLClients)
            {
                ((ChatClient)(c.Value)).sendMessage(message + Environment.NewLine);
            }
        }

    }

FR:海涛高软(Hunk Xu)  QQ技术交流群:386476712

没有更多推荐了,返回首页