⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionmanager.cs

📁 GPRS开发系列文章之实战篇,源码尅有作为研究对象
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.ComponentModel;

namespace GRRSServer
{
    public class ConnectionManager
    {
        /// <summary>
        /// 用于处理每个请求的socket
        /// </summary>
        private Socket socket;

        //客户端用户名
        private string clientName;
        /// <summary>
        /// 客户端用户名
        /// </summary>
        public string ClientName
        {
            get { return this.clientName; }
            set { this.clientName = value; }
        }

        /// <summary>
        /// 获取已成功连接服务器的客户IP.
        /// </summary>
        public IPAddress IP
        {
            get
            {
                if (this.socket != null)
                    return ((IPEndPoint)this.socket.RemoteEndPoint).Address;
                else
                    return IPAddress.None;
            }
        }
        /// <summary>
        /// 获取已成功连接服务器的客户端口.如果连接失败则为-1
        /// </summary>
        public int Port
        {
            get
            {
                if (this.socket != null)
                    return ((IPEndPoint)this.socket.RemoteEndPoint).Port;
                else
                    return -1;
            }
        }
        /// <summary>
        /// 指示远程客户端是否已经建立了连接
        /// </summary>
        public bool Connected
        {
            get
            {
                if (this.socket != null)
                    return this.socket.Connected;
                else
                    return false;
            }
        }
        /// <summary>
        /// 用于连接成功后读取客户端发送数据的网络流
        /// </summary>
        private NetworkStream networkStream;

        /// <summary>
        /// background worker
        /// </summary>
        private BackgroundWorker bwReceiver;

        public ConnectionManager(Socket clientSocket)
        {
            this.socket = clientSocket;
            this.networkStream = new NetworkStream(this.socket);
            this.bwReceiver = new BackgroundWorker();
            this.bwReceiver.DoWork += new DoWorkEventHandler(StartReceive);
            this.bwReceiver.RunWorkerAsync();
        }

        /// <summary>
        /// 开始接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartReceive(object sender, DoWorkEventArgs e)
        {
            while(this.socket.Connected)
            {
                if(networkStream.CanRead)
                {
                    byte[] buffer = new byte[56];
                    int readBytes = this.networkStream.Read(buffer, 0, buffer.GetLength(0));
                    if (readBytes == 0)
                        break;

                    string cmdMetaData = System.Text.Encoding.Default.GetString(buffer, 0, buffer.GetLength(0));
                    buffer = Encoding.Unicode.GetBytes(cmdMetaData);

                    if (cmdMetaData.Length > 0)
                    {
                        clientName = cmdMetaData.Split(new char[] { ':' })[0];
                        OnClientReceived(new ClientEventArgs(this.socket, cmdMetaData));
                    }  

                }
            }

            this.OnDisconnected(new ClientEventArgs(this.socket,"disconn"));
            this.Disconnect();
        }

        private void bwSender_DoWork(object sender, DoWorkEventArgs e)
        {
            Command cmd = (Command)e.Argument;
            e.Result = this.SendCommandToClient(cmd);
        }

        //This Semaphor is to protect the critical section from concurrent access of sender threads.
        System.Threading.Semaphore semaphor = new System.Threading.Semaphore(1, 1);
        /// <summary>
        /// 向指定客户端发送数据
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private bool SendCommandToClient(Command cmd)
        {
            try
            {
                semaphor.WaitOne();
                string strSentInfo = string.Empty;
                strSentInfo = string.Format("发送者:{0}{1}内容:{2}", cmd.SenderName, Environment.NewLine, cmd.MetaData);

                byte[] buffer = new byte[256];
                buffer = System.Text.Encoding.Default.GetBytes(strSentInfo);
                this.networkStream.Write(buffer, 0, buffer.GetLength(0));
                this.networkStream.Flush();               
               
                semaphor.Release();
                return true;
            }
            catch
            {
                semaphor.Release();
                return false;
            }
        }
        /// <summary>
        /// 向客户端发送命令
        /// </summary>
        /// <param name="cmd"></param>
        public void SendCommand(Command cmd)
        {
            if (this.socket != null && this.socket.Connected)
            {
                BackgroundWorker bwSender = new BackgroundWorker();
                bwSender.DoWork += new DoWorkEventHandler(bwSender_DoWork);
                bwSender.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSender_RunWorkerCompleted);
                bwSender.RunWorkerAsync(cmd);
            }
            else
                this.OnCommandFailed(new EventArgs());
        }

        private void bwSender_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null && ((bool)e.Result))
                this.OnCommandSent(new EventArgs());
            else
                this.OnCommandFailed(new EventArgs());

            ((BackgroundWorker)sender).Dispose();
            GC.Collect();
        }

        /// <summary>
        /// Disconnect the current client manager from the remote client and returns true if the client had been disconnected from the server.
        /// </summary>
        /// <returns>True if the remote client had been disconnected from the server,otherwise false.</returns>
        public bool Disconnect()
        {
            if (this.socket != null && this.socket.Connected)
            {
                try
                {
                    this.socket.Shutdown(SocketShutdown.Both);
                    this.socket.Close();
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else
                return true;
        } 

        /// <summary>
        /// 从客户端接收到请求事件
        /// </summary>
        public event ClientReceivedEventHandler ClientReceived;
        /// <summary>
        /// 从客户端接收到请求
        /// </summary>
        /// <param name="e">Received command.</param>
        protected virtual void OnClientReceived(ClientEventArgs e)
        {
            if (ClientReceived != null)
                ClientReceived(this, e);
        }

        /// <summary>
        /// 向客户端发送命令成功事件
        /// </summary>
        public event CommandSentEventHandler CommandSent;
        /// <summary>
        /// 向客户端发送命令成功
        /// </summary>
        /// <param name="e">The sent command.</param>
        protected virtual void OnCommandSent(EventArgs e)
        {
            if (CommandSent != null)
                CommandSent(this, e);
        }

        /// <summary>
        ///向客户端发送数据失败事件
        /// </summary>
        public event CommandSendingFailedEventHandler CommandFailed;
        /// <summary>
        /// 向客户端发送数据失败.引起的原因可能是客户端已关闭连接或者发送中出现错误
        /// </summary>
        /// <param name="e">The sent command.</param>
        protected virtual void OnCommandFailed(EventArgs e)
        {
            if (CommandFailed != null)
                CommandFailed(this, e);
        }

        /// <summary>
        /// 断开连接时引发该事件
        /// </summary>
        public event DisconnectedEventHandler Disconnected;
        /// <summary>
        /// 断开连接时引发该事件
        /// </summary>
        /// <param name="e">Client information.</param>
        protected virtual void OnDisconnected(ClientEventArgs e)
        {
            if (Disconnected != null)
                Disconnected(this, e);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -