C # asynchronous Socket Tcp server implementation

Source: Internet
Author: User

C # asynchronous Socket Tcp server implementation
Introduction

In c #, Microsoft has provided TcpListener and TcpClient to achieve Tcp communication, this Part has been written by some people to better Asynchronous Server code http://www.cnblogs.com/gaochundong/archive/2013/04/14/csharp_async_tcp_server.html this blogger wrote blog quality is really high, I often browse his blog and there is always a lot of surprises for me. He uses TcpListener to Implement Asynchronous servers.

In essence, my socket version is no different from his. I just changed it a little bit, so I just paste a piece of code here, so I will not explain it much.

Code server core code AsyncServer. cs
////// Asynchronous SOCKET server ///Public class AsyncServer: IDisposable {# region Fields ////// Maximum number of client connections allowed by the server program ///Private int _ maxClient ;////// Number of clients currently connected ///Private int _ clientCount ;////// Asynchronous socket used by the server ///Private Socket _ serverSock ;////// Client Session list ///Private List
 
  
_ Clients; private bool disposed = false; # endregion # region Properties ///
  /// Whether the server is running ///Public bool IsRunning {get; private set ;}///
  /// IP address of the listener ///Public IPAddress Address {get; private set ;}///
  /// Listening port ///Public int Port {get; private set ;}///
  /// Encoding used for communication ///Public Encoding {get; set ;}# endregion # region Ctors ///
  /// Asynchronous Socket TCP server //////
  Listener Port public AsyncServer (int listenPort): this (IPAddress. Any, listenPort, 1024 ){}///
  /// Asynchronous Socket TCP server //////
  Listener endpoint public AsyncServer (IPEndPoint localEP): this (localEP. Address, localEP. Port, 1024 ){}///
  /// Asynchronous Socket TCP server //////
  IP address of the listener ///
  Listening port ///
  Maximum number of clients: public AsyncServer (IPAddress localIPAddress, int listenPort, int maxClient) {this. address = localIPAddress; this. port = listenPort; this. encoding = Encoding. default; _ maxClient = maxClient; _ clients = new List
  
   
(); _ ServerSock = new Socket (localIPAddress. AddressFamily, SocketType. Stream, ProtocolType. Tcp);} # endregion # region Server ///
   /// Start the server //////
   
    
Asynchronous TCP Server
   Public AsyncServer Start () {if (! IsRunning) {IsRunning = true; _ serverSock. bind (new IPEndPoint (this. address, this. port); _ serverSock. listen (1024); _ serverSock. beginAccept (new AsyncCallback (HandleAcceptConnected), _ serverSock);} return this ;}///
   /// Start the server //////
   /// Maximum length of the suspended connection sequence allowed by the server //////
   
    
Asynchronous TCP Server
   Public AsyncServer Start (int backlog) {if (! IsRunning) {IsRunning = true; _ serverSock. bind (new IPEndPoint (this. address, this. port); _ serverSock. listen (backlog); _ serverSock. beginAccept (new AsyncCallback (HandleAcceptConnected), _ serverSock);} return this ;}///
   /// Stop the server //////
   
    
Asynchronous TCP Server
   Public AsyncServer Stop () {if (IsRunning) {IsRunning = false; _ serverSock. close (); // TODO Close the connection to all clients} return this ;}# endregion # region Receive ///
   /// Process client connection //////
   Private void HandleAcceptConnected (IAsyncResult ar) {if (IsRunning) {Socket server = (Socket) ar. asyncState; Socket client = server. endAccept (ar); // check whether the maximum number of allowed clients is reached. if (_ clientCount = _ maxClient) {// TODO trigger event RaiseServerException (null );} else {Session session = new Session (client); lock (_ clients) {_ clients. add (session); _ clientCount ++; RaiseClientConnected (session); // triggers Client Connection events} session. recvDataBuffer = new byte [client. receiveBufferSize]; // starts to accept the Data client from this client. beginReceive (session. recvDataBuffer, 0, session. recvDataBuffer. length, SocketFlags. none, new AsyncCallback (HandleDataReceived), session);} // receives the next request server. beginAccept (new AsyncCallback (HandleAcceptConnected), ar. asyncState );}}///
   /// Process client data //////
   Private void HandleDataReceived (IAsyncResult ar) {if (IsRunning) {Session session = (Session) ar. asyncState; Socket client = session. clientSocket; try {// If asynchronous receiving is started twice, the client will execute EndReceive int recv = client twice when exiting. endReceive (ar); if (recv = 0) {// TODO trigger event (close client) CloseSession (session); RaiseNetError (session); return ;} // TODO processes read data ps: RaiseDataReceived (session) in the RecvDataBuffer of the session; // TODO triggers the Data Receiving Event} catch (SocketException ex) {// TODO Exception Handling RaiseNetError (session);} finally {// continue to receive data from the client. beginReceive (session. recvDataBuffer, 0, session. recvDataBuffer. length, SocketFlags. none, new AsyncCallback (HandleDataReceived), session) ;}}# endregion # region Send ///
   /// Send data //////
   Client Session for receiving data ///
   Public void Send (Session session, byte [] data) {Send (session. ClientSocket, data );}///
   /// Send data asynchronously to the specified client //////
   Client ///
   Public void Send (Socket client, byte [] data) {if (! IsRunning) throw new InvalidProgramException (This TCP Scoket server has not been started .); if (client = null) throw new ArgumentNullException (client); if (data = null) throw new ArgumentNullException (data); client. beginSend (data, 0, data. length, SocketFlags. none, new AsyncCallback (SendDataEnd), client );}///
   /// Processing function for data transmission completion //////
   Target client Socket private void SendDataEnd (IAsyncResult ar) {(Socket) ar. AsyncState). EndSend (ar) ;}# endregion # region Events ///
   /// Receives the data event ///Public event EventHandler
   
    
DataReceived; private void RaiseDataReceived (Session session) {if (DataReceived! = Null) {DataReceived (this, new AsyncEventArgs (session ));}}///
    /// The connection to the client has been established ///Public event EventHandler ClientConnected ;///
    /// Disconnection event with the client ///Public event EventHandler ClientDisconnected ;///
    /// Trigger the client connection event //////
    Private void RaiseClientConnected (Session session) {if (ClientConnected! = Null) {ClientConnected (this, new AsyncEventArgs (session ));}}///
    /// Trigger the client connection disconnection event //////
    Private void RaiseClientDisconnected (Socket client) {if (ClientDisconnected! = Null) {ClientDisconnected (this, new AsyncEventArgs (disconnected ));}}///
    /// Network error event ///Public event EventHandler NetError ;///
    /// Trigger a network error //////
    Private void RaiseNetError (Session session) {if (NetError! = Null) {NetError (this, new AsyncEventArgs (session ));}}///
    /// Exception event ///Public event EventHandler ServerException ;///
    /// Trigger an exception //////
    Private void RaiseServerException (Session session) {if (ServerException! = Null) {ServerException (this, new AsyncEventArgs (session) ;}# endregion # region Close ///
    /// Close a session with the client //////
    Public void CloseSession (Session session) {if (session! = Null) {session. datasync = null; session. recvDataBuffer = null; _ clients. remove (session); _ clientCount --; // TODO triggers closing event session. close ();}}///
    /// Close all client sessions and disconnect from all clients ///Public void CloseAllClient () {foreach (Session client in _ clients) {CloseSession (client);} _ clientCount = 0; _ clients. Clear ();}///
    /// Performs application-defined tasks associated with freeing, // releasing, or resetting unmanaged resources .///Public void Dispose () {Dispose (true); GC. SuppressFinalize (this );}///
    /// Releases unmanaged and-optionally-managed resources //////
    
    
     
True
    To release // both managed and unmanaged resources;
    
     
False
    /// To release only unmanaged resources. protected virtual void Dispose (bool disposing) {if (! This. disposed) {if (disposing) {try {Stop (); if (_ serverSock! = Null) {_ serverSock = null ;}} catch (SocketException ex) {// TODO RaiseServerException (null) ;}} disposed = true ;}# endregion}
   
  
 

A Session class is used to encapsulate the connection Session to the client, cs
////// Session class between the client and the server ///Public class Session {# region field ////// Receiving data buffer ///Private byte [] _ recvBuffer ;////// The message sent from the client to the server // note: In some cases, the message may be a part of the message but not complete ///Private string _ datasync ;////// Client Socket ///Private Socket _ clientSock; # endregion # region attributes ////// Receiving data buffer ///Public byte [] RecvDataBuffer {get {return _ recvBuffer;} set {_ recvBuffer = value ;}}////// Access the session message ///Public string datasync {get {return _ datax;} set {_ datax = value ;}}////// Obtain the Socket object associated with the client session ///Public Socket ClientSocket {get {return _ clientSock; }}# endregion ////// Constructor //////The Socket used by the Session to connect to the public Session (Socket cliSock) {_ clientSock = cliSock ;}////// Close the session ///Public void Close () {// Close data receiving and sending _ clientSock. Shutdown (SocketShutdown. Both); // clear resource _ clientSock. Close ();}}

Event Type
Class AsyncEventArgs: EventArgs {////// Prompt message ///Public string _ msg; public Session _ sessions ;////// Whether it has been processed ///Public bool IsHandled {get; set;} public AsyncEventArgs (string msg) {this. _ msg = msg; IsHandled = false;} public AsyncEventArgs (Session session) {this. _ sessions = session; IsHandled = false;} public AsyncEventArgs (string msg, Session session) {this. _ msg = msg; this. _ sessions = session; IsHandled = false ;}}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.