MushinyTcpServer.cs 10.0 KB
using log4net;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Mushiny
{
    public class MushinyTcpServer
    {
        public static readonly ILog LOGGER = Common.LOGGER;
        /// <summary>
        /// 接受消息时的间隔
        /// </summary>
        public static int ReviceMsgMS = 10;

        private Thread m_serverThread;
        private Socket m_serverSocket;
        public delegate void ReviceMsg(TcpClientBean client, string Msg);
        public delegate void ReviceMsgBytes(TcpClientBean client, byte[] Msg);
        public event ReviceMsg ReviceMsgEvent;
        public event ReviceMsgBytes ReviceMsgBytesEvent;
        private delegate void ReceiveMessageDelegate(TcpClientBean client);

        public event AcceptClientDelegate AcceptClientEvent;
        public delegate void AcceptClientDelegate(TcpClientBean client);
        ReceiveMessageDelegate receiveMessageDelegate;
        private bool isRun = true;
        private int serverPort = 0;


        private void logLocalIp()
        {
            string[] addresses = GetLocalAddresses();
            string iplist = "本机IP:[";
            if (addresses.Length > 0)
            {
                for (int i = 0; i < addresses.Length; i++)
                {
                    if (addresses.Length != 0)
                    {
                        iplist = iplist + " " + addresses[i];
                    }
                }
            }
            LOGGER.Info(iplist + "]");
        }

        /// <summary>
        /// 开始服务
        /// </summary>
        public void Start(int m_serverPort)
        {
            try
            {
                isRun = true;
                m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, m_serverPort);
                this.serverPort = m_serverPort;
                m_serverSocket.Bind(localEndPoint);
                m_serverSocket.Listen(10);

                m_serverThread = new Thread(new ThreadStart(ReceiveAccept));
                m_serverThread.Start();

                LOGGER.Info(" Server start listen : " + m_serverPort);
                logLocalIp();

                //this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Server started.");
            }
            catch (SocketException se)
            {
                throw new Exception(se.Message);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        public void Stop()
        {
            try
            {
                isRun = false;
                m_serverThread.Interrupt(); // 线程终止
                m_serverSocket.Close(); // Socket Close  
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private void ReceiveAccept()
        {
            while (isRun)
            {
                TcpClientBean client = new TcpClientBean();
                try
                {
                    client.ClientSocket = m_serverSocket.Accept();
                    IPEndPoint clientipe = (IPEndPoint)client.ClientSocket.RemoteEndPoint;
                    client.AddStr = clientipe.Address.ToString() + ":" + clientipe.Port.ToString();
                    LOGGER.Info("[" + serverPort + "]有新的客户端链接上:[" + client.AddStr + "]");
                    AcceptClientEvent?.Invoke(client);

                    receiveMessageDelegate = new ReceiveMessageDelegate(ReceiveMessages);
                    receiveMessageDelegate.BeginInvoke(client, ReceiveMessagesCallback, "");
                }
                catch (Exception ex)
                {
                    LOGGER.Error("ReceiveAccept方法,客户端【" + client.AddStr + "】:" + ex.Message);
                    //throw new Exception(ex.Message);
                }
            }
        }
        //   private StringBuilder sb = new StringBuilder();             //这个是用来保存:接收到了的,但是还没有结束的消息
        private int receiveBufferSize = 1024;
        private string terminateString = "\r";
        public void ReceiveMessages(TcpClientBean client)            //这个函数会被以线程方式运行
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                Socket socket = (Socket)client.ClientSocket;
                while (true)
                {
                    byte[] buffer = new byte[receiveBufferSize];  //buffer大小,此处为1024
                    int receivedSize = socket.Receive(buffer);
                    if (receivedSize > 0)
                    {
                        ReviceMsgBytesEvent?.Invoke(client, Common.GetSubBytes(buffer, 0, receivedSize));
                        //string rawMsg = Encoding.ASCII.GetString(buffer, 0, receivedSize);
                        //int rnFixLength = terminateString.Length;   //这个是指消息结束符的长度,此处为\r\n
                        //for (int i = 0; i < rawMsg.Length;)               //遍历接收到的整个buffer文本
                        //{
                        //    if (i <= rawMsg.Length - rnFixLength)
                        //    {
                        //        if (rawMsg.Substring(i, rnFixLength) != terminateString)//非消息结束符,则加入sb
                        //        {
                        //            sb.Append(rawMsg[i]);
                        //            i++;
                        //        }
                        //        else
                        //        {
                        //            this.ReviceMsgEvent.Invoke(client, sb?.ToString());//找到了消息结束符,触发消息接收完成事件
                        //            sb = new StringBuilder();
                        //            i += rnFixLength;
                        //        }
                        //    }
                        //    else
                        //    {
                        //        sb.Append(rawMsg[i]);
                        //        i++;
                        //    }
                        //}
                    }

                    Thread.Sleep(ReviceMsgMS);
                }
            }
            catch (SocketException e)
            {
                LOGGER.Error("客户端{" + client.AddStr + "]:" + e.ToString());
            }
            catch (Exception ex)
            {
                LOGGER.Error("客户端{" + client.AddStr + "]:" + ex.ToString());
            }
        }
        //private void ReceiveMessages(Client client)
        //{
        //    try
        //    {
        //        while (true)
        //        {
        //            byte[] receiveBuffer = new byte[1024];

        //            //int size = ;
        //            int size = client.ClientSocket.Receive(receiveBuffer);

        //            string strReceiveData = Encoding.ASCII.GetString(receiveBuffer, 0, size);

        //            if (!string.IsNullOrEmpty(strReceiveData))
        //            {
        //                LogUtil.info(LOGGER, "收到数据:" + strReceiveData);
        //                // this.AddRunningInfo(">> Receive data from [" + client.ClientSocket.RemoteEndPoint.ToString()+ "]:" + strReceiveData);
        //                string strSendData = "OK. The content is:" + strReceiveData;
        //                //LogUtil.info(LOGGER, "OK. The content is:" + strReceiveData);
        //                int sendBufferSize = Encoding.Unicode.GetByteCount(strSendData);
        //                byte[] sendBuffer = new byte[sendBufferSize];
        //                sendBuffer = Encoding.Unicode.GetBytes(strSendData);

        //                client.ClientSocket.Send(sendBuffer);
        //            }
        //        }
        //    }
        //    catch (SocketException e)
        //    {
        //        LogUtil.error(LOGGER, e.ToString());
        //    }
        //    catch (Exception ex)
        //    {
        //        LOGGER.Error(ex.ToString());
        //    }
        //}

        private void ReceiveMessagesCallback(IAsyncResult AR)
        {
            try
            {
                receiveMessageDelegate.EndInvoke(AR);
            }
            catch (Exception ex)
            {
                LOGGER.Error(ex.ToString());
            }
        }

        /// <summary>
        /// 获取本机地址列表
        /// </summary>
        public string[] GetLocalAddresses()
        {
            // 获取主机名
            string strHostName = Dns.GetHostName();

            // 根据主机名进行查找
            IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);

            string[] retval = new string[iphostentry.AddressList.Length];

            int i = 0;
            foreach (IPAddress ipaddress in iphostentry.AddressList)
            {
                if (ipaddress.AddressFamily != AddressFamily.InterNetworkV6)
                {
                    retval[i] = ipaddress.ToString();
                    i++;
                }
            }
            return retval;
        }
    }

    /// <summary>
    /// 客户端会话信息类
    /// </summary>
    public class TcpClientBean
    {
        Socket m_clientSocket;

        public TcpClientBean() { }
        public string AddStr = "";
        //Console.WriteLine("I am connected to " + IPAddress.Parse(((IPEndPoint)s.RemoteEndPoint).Address.ToString()) + "on port number " + ((IPEndPoint)s.RemoteEndPoint).Port.ToString());

        public string IP
        {
            get
            {
                return ((IPEndPoint)m_clientSocket.RemoteEndPoint).Address.ToString();
            }
        }
        public int Port
        {
            get { return ((IPEndPoint)m_clientSocket.RemoteEndPoint).Port; }
        }
        public Socket ClientSocket
        {
            get { return m_clientSocket; }
            set { this.m_clientSocket = value; }
        }
    }

}