• C#网络编程系列(两)它Socket同步TCPserver


    声明原文

    笔者:竹zz  本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处

    文章系列文件夹

    C#网络编程系列文章(一)之Socket实现异步TCPserver 

    C#网络编程系列文章(二)之Socket实现同步TCPserver

    C#网络编程系列文章(三)之TcpListener实现异步TCPserver

    C#网络编程系列文章(四)之TcpListener实现同步TCPserver

    C#网络编程系列文章(五)之Socket实现异步UDPserver

    C#网络编程系列文章(六)之Socket实现同步UDPserver

    C#网络编程系列文章(七)之UdpClient实现异步UDPserver

    C#网络编程系列文章(八)之UdpClient实现同步UDPserver


    本文介绍

    在上一篇博客中我说了,我将会介绍c#中使用Socket和TcpListener和UdpClient实现各种同步和异步的TCP和UDPserver,这些都是是我自己花了非常多天的时间来总结的。这样一来相信刚接触c#网络编程的朋友们不会像曾经的我一样到处出找资料,到处调试。本次我介绍的是使用Socket来实现的同步的TCPserver,同步的TCPserver和第一篇里面介绍的异步TCPserver的差别就是,在Socket调用Accept的时候是否会堵塞。

    同步的TCPserver在接受到一个client的请求的时候通常是开启一个线程去处理和这个client的通信工作,这样的方式的不好的地方就是资源消耗大。可是假如使用线程池的话,事先分配一定数量的线程。性能还是能够。

    可是我之所以给出非常多方法实现的server,主要目的就是想測试哪种情况性能比較不错,就眼下来看,异步的模式比較NICE,可是事实上另一种IOCP模式性能是最好的。。。

    Socket同步TCPserver

    服务端代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    
    namespace NetFrame.Net.TCP.Sock.Synchronous
    {
        /// <summary>
        /// 基于socket实现的同步TCPserver
        /// </summary>
        public class SocketTCPServer
        {
            #region Fields
            /// <summary>
            /// server程序同意的最大客户端连接数
            /// </summary>
            private int _maxClient;
    
            /// <summary>
            /// 当前的连接的客户端数
            /// </summary>
            private int _clientCount;
    
            /// <summary>
            /// server使用的异步socket
            /// </summary>
            private Socket _serverSock;
    
            /// <summary>
            /// 客户端会话列表
            /// </summary>
            private List<SocketClientHandle> _clients;
    
            private bool disposed = false;
    
            #endregion
    
            #region Properties
    
            /// <summary>
            /// server是否正在执行
            /// </summary>
            public bool IsRunning { get; private set; }
            /// <summary>
            /// 监听的IP地址
            /// </summary>
            public IPAddress Address { get; private set; }
            /// <summary>
            /// 监听的port
            /// </summary>
            public int Port { get; private set; }
            /// <summary>
            /// 通信使用的编码
            /// </summary>
            public Encoding Encoding { get; set; }
    
    
            #endregion
    
            #region 构造函数
            /// <summary>
            /// 同步Socket TCPserver
            /// </summary>
            /// <param name="listenPort">监听的port</param>
            public SocketTCPServer(int listenPort)
                : this(IPAddress.Any, listenPort, 1024)
            {
            }
    
            /// <summary>
            /// 同步Socket TCPserver
            /// </summary>
            /// <param name="localEP">监听的终结点</param>
            public SocketTCPServer(IPEndPoint localEP)
                : this(localEP.Address, localEP.Port, 1024)
            {
            }
    
            /// <summary>
            /// 同步Socket TCPserver
            /// </summary>
            /// <param name="localIPAddress">监听的IP地址</param>
            /// <param name="listenPort">监听的port</param>
            /// <param name="maxClient">最大客户端数量</param>
            public SocketTCPServer(IPAddress localIPAddress, int listenPort, int maxClient)
            {
                this.Address = localIPAddress;
                this.Port = listenPort;
                this.Encoding = Encoding.Default;
    
                _maxClient = maxClient;
                _clients = new List<SocketClientHandle>();
                _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            }
    
            #endregion
    
            #region Method
            /// <summary>
            /// 启动server
            /// </summary>
            public void Start()
            {
                if (!IsRunning)
                {
                    IsRunning = true;
                    _serverSock.Bind(new IPEndPoint(this.Address, this.Port));
                    Thread thread = new Thread(StartListen);
                    thread.Start();
    
                }
            }
            /// <summary>
            /// 開始进行监听
            /// </summary>
            private void StartListen()
            {
                _serverSock.Listen(1024);
                SocketClientHandle handle;
                while (IsRunning)
                {
                    if (_clientCount >= _maxClient)
                    {
                        //TODO 客户端过多异常
                        RaiseOtherException(null);
                    }
                    else
                    {
                        Socket clientSock = _serverSock.Accept();
                        _clientCount++;
                        //TODO 创建一个处理客户端的线程并启动
                        handle = new SocketClientHandle(clientSock);
                        _clients.Add(handle);
                        //使用线程池来操作
                        ThreadPool.QueueUserWorkItem(new WaitCallback(handle.RecevieData));
    
                        //Thread pthread;
                        //pthread = new Thread(new ThreadStart(client.RecevieData));
                        //pthread.Start();
                        //这里应该使用线程池来进行
                    }
                }
    
            }
            /// <summary>
            /// 停止server
            /// </summary>
            public void Stop()
            {
                if (IsRunning)
                {
                    IsRunning = false;
                    _serverSock.Close();
                    //TODO 关闭对全部客户端的连接
    
                }
            }
            /// <summary>
            /// 发送函数
            /// </summary>
            public void Send(string msg, SocketClientHandle client)
            {
                //TODO
            }
    
            /// <summary>
            /// 关闭一个与客户端之间的会话
            /// </summary>
            /// <param name="handle">须要关闭的客户端会话对象</param>
            public void Close(SocketClientHandle handle)
            {
                if (handle != null)
                {
                    _clients.Remove(handle);
                    handle.Dispose();
                    _clientCount--;
                    //TODO 触发关闭事件
                    
                }
            }
            /// <summary>
            /// 关闭全部的客户端会话,与全部的客户端连接会断开
            /// </summary>
            public void CloseAllClient()
            {
                foreach (SocketClientHandle handle in _clients)
                {
                    Close(handle);
                }
                _clientCount = 0;
                _clients.Clear();
            }
    
            #endregion
    
            #region 事件
    
            /// <summary>
            /// 与客户端的连接已建立事件
            /// </summary>
            public event EventHandler<SocketEventArgs> ClientConnected;
            /// <summary>
            /// 与客户端的连接已断开事件
            /// </summary>
            public event EventHandler<SocketEventArgs> ClientDisconnected;
    
            /// <summary>
            /// 触发客户端连接事件
            /// </summary>
            /// <param name="state"></param>
            private void RaiseClientConnected(SocketClientHandle handle)
            {
                if (ClientConnected != null)
                {
                    ClientConnected(this, new SocketEventArgs(handle));
                }
            }
            /// <summary>
            /// 触发客户端连接断开事件
            /// </summary>
            /// <param name="client"></param>
            private void RaiseClientDisconnected(Socket client)
            {
                if (ClientDisconnected != null)
                {
                    ClientDisconnected(this, new SocketEventArgs("连接断开"));
                }
            }
    
            /// <summary>
            /// 接收到数据事件
            /// </summary>
            public event EventHandler<SocketEventArgs> DataReceived;
    
            private void RaiseDataReceived(SocketClientHandle handle)
            {
                if (DataReceived != null)
                {
                    DataReceived(this, new SocketEventArgs(handle));
                }
            }
    
            /// <summary>
            /// 数据发送事件
            /// </summary>
            public event EventHandler<SocketEventArgs> CompletedSend;
    
            /// <summary>
            /// 触发数据发送事件
            /// </summary>
            /// <param name="state"></param>
            private void RaiseCompletedSend(SocketClientHandle handle)
            {
                if (CompletedSend != null)
                {
                    CompletedSend(this, new SocketEventArgs(handle));
                }
            }
    
    
            /// <summary>
            /// 网络错误事件
            /// </summary>
            public event EventHandler<SocketEventArgs> NetError;
            /// <summary>
            /// 触发网络错误事件
            /// </summary>
            /// <param name="state"></param>
            private void RaiseNetError(SocketClientHandle handle)
            {
                if (NetError != null)
                {
                    NetError(this, new SocketEventArgs(handle));
                }
            }
    
            /// <summary>
            /// 异常事件
            /// </summary>
            public event EventHandler<SocketEventArgs> OtherException;
            /// <summary>
            /// 触发异常事件
            /// </summary>
            /// <param name="state"></param>
            private void RaiseOtherException(SocketClientHandle handle, string descrip)
            {
                if (OtherException != null)
                {
                    OtherException(this, new SocketEventArgs(descrip, handle));
                }
            }
            private void RaiseOtherException(SocketClientHandle handle)
            {
                RaiseOtherException(handle, "");
            }
    
            #endregion
    
            #region Close 未实现
            #endregion
    
            #region 释放
            /// <summary>
            /// Performs application-defined tasks associated with freeing, 
            /// releasing, or resetting unmanaged resources.
            /// </summary>
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            /// <summary>
            /// Releases unmanaged and - optionally - managed resources
            /// </summary>
            /// <param name="disposing"><c>true</c> to release 
            /// both managed and unmanaged resources; <c>false</c> 
            /// to release only unmanaged resources.</param>
            protected virtual void Dispose(bool disposing)
            {
                if (!this.disposed)
                {
                    if (disposing)
                    {
                        try
                        {
                            Stop();
                            if (_serverSock != null)
                            {
                                _serverSock = null;
                            }
                        }
                        catch (SocketException)
                        {
                            //TODO 异常
                        }
                    }
                    disposed = true;
                }
            }
            #endregion
        }
    }
    

    对client操作封装的Handle类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    
    namespace NetFrame.Net.TCP.Sock.Synchronous
    {
        /// <summary>
        /// Socket server用于处理客户端连接封装的客户端处理类
        /// </summary>
        public class SocketClientHandle:IDisposable
        {
            /// <summary>
            /// 与客户端相关联的socket
            /// </summary>
            private Socket _client;
    
            /// <summary>
            /// 标识是否与客户端相连接
            /// </summary>
            private bool _is_connect;
            public bool IsConnect
            {
                get { return _is_connect; }
                set { _is_connect = value; }
            }
    
            /// <summary>
            /// 数据接受缓冲区
            /// </summary>
            private byte[] _recvBuffer;
    
            public SocketClientHandle(Socket client)
            {
                this._client = client;
                _is_connect = true;
                _recvBuffer = new byte[1024 * 1024 * 2];
            }
    
            #region Method
            /// <summary>
            /// 接受来自客户端发来的数据
            /// </summary>
            public void RecevieData(Object state)
            {
                int len = -1;
                while (_is_connect)
                {
                    try
                    {
                        len = _client.Receive(_recvBuffer);
                    }
                    catch (Exception)
                    {
                        //TODO
                    }
                }
            }
    
            /// <summary>
            /// 向客户端发送数据
            /// </summary>
            public void SendData(string msg)
            {
                byte[] data = Encoding.Default.GetBytes(msg);
                try
                {
                    //有一种比較好的写法
                    _client.Send(data);
                }
                catch (Exception)
                {
                    //TODO 处理异常
                }
            }
    
            #endregion
    
    
            #region 事件
    
    
            //TODO 消息发送事件
            //TODO 数据收到事件
            //TODO 异常处理事件
    
            #endregion
    
            #region 释放
            /// <summary>
            /// Performs application-defined tasks associated with freeing, 
            /// releasing, or resetting unmanaged resources.
            /// </summary>
            public void Dispose()
            {
                _is_connect = false;
                if (_client != null)
                {
                    _client.Close();
                    _client = null;
                }
                GC.SuppressFinalize(this);
            }
    
            #endregion
        }
    }
    

    Socket同步TCPserver的时间參数类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace NetFrame.Net.TCP.Sock.Synchronous
    {
        /// <summary>
        /// 同步Socket TCPserver事件类
        /// </summary>
        public class SocketEventArgs : EventArgs
        {
            /// <summary>
            /// 提示信息
            /// </summary>
            public string _msg;
    
            /// <summary>
            /// client状态封装类
            /// </summary>
            public SocketClientHandle _handle;
    
            /// <summary>
            /// 是否已经处理过了
            /// </summary>
            public bool IsHandled { get; set; }
    
            public SocketEventArgs(string msg)
            {
                this._msg = msg;
                IsHandled = false;
            }
            public SocketEventArgs(SocketClientHandle handle)
            {
                this._handle = handle;
                IsHandled = false;
            }
            public SocketEventArgs(string msg, SocketClientHandle handle)
            {
                this._msg = msg;
                this._handle = handle;
                IsHandled = false;
            }
        }
    }
    

    本文作者:小竹zz  本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处




    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    2019JAVA第三次实验报告
    第二次作业
    第一周作业
    2019年春总结
    第二周作业
    第十二周作业
    第十一周作业
    第十周作业
    第九周作业
    第八周作业
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4628567.html
Copyright © 2020-2023  润新知