C \ # 네트워크 프로 그래 밍 시리즈 (2) 소켓 동기 화 TCPserver

16401 단어 socket
성명 원문
필자: 죽 즈 본문 주소http://blog.csdn.net/zhujunxxxxx/article/details/44258719 전재 출처 를 밝 혀 주 십시오
글 시리즈 폴 더
C \ # 네트워크 프로 그래 밍 시리즈 글 (1) 의 Socket 은 비동기 TCPserver 를 실현 합 니 다.  
C \ # 네트워크 프로 그래 밍 시리즈 글 (2) 의 Socket 동기 화 TCPserver 구현
C \ # 네트워크 프로 그래 밍 시리즈 글 (3) 의 TcpListener 비동기 TCPserver 구현
C \ # 네트워크 프로 그래 밍 시리즈 글 (4) 의 TcpListener 동기 화 TCPserver 구현
C \ # 네트워크 프로 그래 밍 시리즈 글 (5) 의 Socket 은 비동기 UDPServer 를 실현 합 니 다.
C \ # 네트워크 프로 그래 밍 시리즈 글 (6) 의 Socket 동기 화 UDPServer
C \ # 네트워크 프로 그래 밍 시리즈 글 (7) 의 UdpClient 가 비동기 UDPServer 를 실현 합 니 다.
C \ # 네트워크 프로 그래 밍 시리즈 글 (8) 의 UdpClient 동기 화 UDPServer 실현
본문 소개
지난 블 로그 에서 나 는 c \ # 에서 Socket 과 TcpListener, UdpClient 를 사용 하여 각종 동기 화 와 비동기 화 를 실현 하 는 TCP 와 UDP server 를 소개 할 것 이 라 고 말 했다. 이것 은 모두 내 가 매우 많은 시간 을 들 여 정리 한 것 이다.이렇게 되면 c \ # 네트워크 프로 그래 밍 을 처음 접 한 친구 들 이 예전 의 나 처럼 자 료 를 찾 아 다 니 며 디 버 깅 을 하지 않 을 것 이 라 고 믿 습 니 다.이번 에는 Socket 을 사용 하여 동기 화 된 TCPserver 를 소개 합 니 다. 동기 화 된 TCPserver 와 첫 번 째 편 에서 소개 한 비동기 TCPserver 의 차 이 는 Socket 에서 Accept 를 호출 할 때 막 히 는 지 여부 입 니 다.
동기 화 된 TCPserver 는 클 라 이언 트 의 요청 을 받 을 때 보통 하나의 스 레 드 를 열 어 이 클 라 이언 트 와 의 통신 작업 을 처리 합 니 다. 이런 방식 이 좋 지 않 은 곳 은 자원 소모 가 크다 는 것 입 니 다.그러나 스 레 드 탱크 를 사용 하면 일정 수량의 스 레 드 를 미리 배정 합 니 다.성능 은 괜찮아 요.
그러나 제 가 여러 가지 방법 으로 이 루어 진 server 를 제시 한 이 유 는 어떤 상황 의 성능 이 비교적 좋 은 지 테스트 하고 자 하 는 것 입 니 다. 눈 으로 보면 비동기 모델 이 NICE 와 비교 되 지만 사실은 다른 IOCP 모델 의 성능 이 가장 좋 습 니 다.
소켓 동기 화 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
    }
}

클 라 이언 트 작업 패키지 핸들 클래스
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;
        }
    }
}

죽방울 본문 주소http://blog.csdn.net/zhujunxxxxx/article/details/44258719 전재 출처 를 밝 혀 주 십시오
저작권 성명: 본 블 로그 의 오리지널 글, 블 로그, 동의 없 이 전재 할 수 없습니다.

좋은 웹페이지 즐겨찾기