C # Asynchronous socket TCP Server implementation

Source: Internet
Author: User

Declaration of originality

This article author: Xiao Bamboo zz This article address: http://blog.csdn.net/zhujunxxxxx reprint please indicate the source.

Introduction I previously wrote a IOCP article: http://blog.csdn.net/zhujunxxxxx/article/details/43573879 This is better than the asynchronous socket, because it is reusable objects.

In C #, Microsoft has provided TcpListener and tcpclient to implement TCP communication, which has been written in some of the better asynchronous server code http://www.cnblogs.com/gaochundong/archive/2013/ 04/14/csharp_async_tcp_server.html This blogger blog quality is really high, I often browse his blog there is always a lot of surprises to me, he used TcpListener to implement the asynchronous server.

My socket version is essentially no different from his, just rewrite a little bit, so put a piece of code here is, many do not explain

Code Server Core Code AsyncServer.cs
<summary>///Async Socket Server///</summary> public class Asyncserver:idisposable {#reg Ion fields///<summary>///The maximum number of client connections allowed by the server program///</summary> private int _maxclien        T        <summary>///Current number of connections///</summary> private int _clientcount;        <summary>///server use asynchronous socket///</summary> private socket _serversock;        <summary>///client Session list///</summary> private list<session> _clients;        private bool disposed = false; #endregion #region Properties//<summary>//Whether the server is running///</summary> PU        blic bool IsRunning {get; private set;}        <summary>////Listening IP address///</summary> public IPAddress address {get; private set;} <summary>///Listening ports///</summary>        public int Port {get; private set;}                <summary>////</summary> public Encoding Encoding {get; set;}        #endregion #region ctors//<summary>//asynchronous socket TCP///</summary> <param name= "listenport" > Monitored ports </param> public asyncserver (int listenport): This (I Paddress.any, listenport,1024) {}//<summary>//asynchronous Socket TCP Server///</sum            mary>//<param name= "localep" > Monitored endpoints </param> public asyncserver (IPEndPoint localEP)        : This (localep.address, localep.port,1024) {}//<summary>//Async Socket TCP Server </summary>//<param name= "localipaddress" > monitored IP address </param>///<param Name= "Li Stenport "> Monitored ports </param>//<param name=" maxclient "> Maximum number of clients </param> Public Asyncserver (IPAddress localipaddress, int. Listenport,int maxclient) {this.            Address = localipaddress; This.            Port = Listenport; This.            Encoding = Encoding.default;            _maxclient = maxclient;            _clients = new list<session> ();        _serversock = new Socket (localipaddress.addressfamily, SocketType.Stream, protocoltype.tcp); #endregion #region Server///<summary>///boot server///</summary>/ <returns> Asynchronous TCP Server </returns> 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; }///<summary>//Start server///</summary>//<param name= "Backlog" >//The maximum length of the pending connection sequence allowed by//server///</param> <returns> Asynchronous TCP Server </returns> 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; }///<summary>//Stop server///</summary>//<returns> Asynchronous TCP Server &LT;/RETURNS&G        T                Public Asyncserver Stop () {if (isrunning) {isrunning = false;                _serversock.close ();        TODO closes the connection to all clients} return this;        #endregion #region Receive//<summary>//Processing client connections</summary>//<param name= "ar" ></param> private void handleacceptconnected (Iasyncresu Lt 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 a client Connection event} session. Recvdatabuffer = new Byte[client.                    Receivebuffersize]; Start accepting data from the client. BeginReceive (session. Recvdatabuffer, 0, SESsion.                Recvdatabuffer.length, Socketflags.none, New AsyncCallback (Handledatareceived), session); }//Accept the next request server. BeginAccept (New AsyncCallback (handleacceptconnected), AR.            asyncstate); }}///<summary>///Processing client data///</summary>//<param name= "AR" >&lt                ;/param> private void handledatareceived (IAsyncResult ar) {if (isrunning) { Session Session = (session) AR.                asyncstate; Socket client = session.                Clientsocket;                    try {//If the asynchronous receive is started two times, so when the client exits//will be executed two times endreceive int recv = client.                    EndReceive (AR); if (recv = = 0) {//todo trigger event (Close client) CloseSession (session                        );                        Raiseneterror (session); ReturN                    //todo processing the data that has been read PS: Data in the session of the Recvdatabuffer raisedatareceived (session);                    TODO trigger data Receive event} catch (SocketException ex) {                TODO exception Handling Raiseneterror (session); Finally {//continues to receive the data client from the clients. BeginReceive (session. Recvdatabuffer, 0, session.                Recvdatabuffer.length, Socketflags.none, New AsyncCallback (Handledatareceived), session); }}} #endregion #region Send//<summary>///&L t;/summary>//<param Name= "Session" > Client session receiving Data </param>//<param name= "Data" > Packet &lt ;/param> public void Send (Session session, byte[] data) {Send (session).        Clientsocket,data); }//<summAry>/////asynchronously send data to the specified client///</summary>//<param name= "Client" > Clients </param>  <param name= "Data" > Messages </param> public void Send (Socket client, byte[] data) {if (!            isrunning) throw new InvalidProgramException ("This TCP Scoket server have 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); }///<summary>///Send data completion processing function///</summary>//<param name= "AR" > Target client sock et</param> private void Senddataend (IAsyncResult ar) {(Socket) ar. asyncstate).        EndSend (AR);   } #endregion #region Events///<summary>///Received data event     </summary> public event eventhandler<eventargs> datareceived;                private void Raisedatareceived (session session) {if (datareceived! = null) {            DataReceived (This, new Asynceventargs (session)); }}////<summary>//Client connection established Event///</summary> public event EventHandler        <AsyncEventArgs> clientconnected; <summary>//connection to client disconnected Event///</summary> public event Eventhandler<asynceventargs        > clientdisconnected;         <summary>///Trigger Client Connection Events///</summary>//<param Name= "session" ></param>                private void Raiseclientconnected (session session) {if (clientconnected! = null) {            Clientconnected (This, new Asynceventargs (session)); }}///<summary>//Trigger Client Connection Disconnect Event///</summary>//<param name= "client" ></param> private void raiseclientdisconnected (Socket client {if (clientdisconnected! = null) {clientdisconnected (this, new Asynceventa            RGS ("Disconnected")); }}///<summary>//Network error events///</summary> public event Eventhandler<as        Ynceventargs> Neterror;        <summary>///Trigger Network error events///</summary>//<param name= "Client" ></param> private void Raiseneterror (session session) {if (neterror! = null) {Ne            Terror (This, new Asynceventargs (session)); }}///<summary>///exception Event///</summary> public event Eventhandler<asyn        Ceventargs> serverexception; <summary>///Trigger Exception events///</summary>//<param name= "Client" &GT;&LT;/PARAM&GT                private void Raiseserverexception (session session) {if (serverexception! = null) {            Serverexception (This, new Asynceventargs (session)); }} #endregion #region Close//<summary>///Shut down a session with the client//</summ ary>//<param name= "Closeclient" > Client Session object that needs to be closed </param> public void CloseSession (Session Sess ION) {if (session! = NULL) {session.                Datagram = null; Session.                Recvdatabuffer = null; _clients.                Remove (session);                _clientcount--; TODO triggers the Shutdown event session.            Close (); }}///<summary>///Close all client sessions, and all client connections will be disconnected///</summary> public void Cl            Oseallclient () {foreach (Session client in _clients) {closesession (client);          }  _clientcount = 0; _clients.        Clear ();  }///<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///&LT;/SUMMARY&GT        ; <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 Disp                    OSE (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 to the client Session,cs
<summary>///client-server session class///</summary> public class Session {#region Field//        <summary>///Receive data buffer///</summary> private byte[] _recvbuffer;  <summary>///client messages sent to server///NOTE: In some cases the message may be a fragment of the message but not complete///</summary> Private        String _datagram;        <summary>//Client socket///</summary> private socket _clientsock; #endregion #region Properties///<summary>//Receive data buffers///</summary> public byte            [] Recvdatabuffer {get {return _recvbuffer;            } set {_recvbuffer = value;        }}///<summary>///Access Message///</summary> public string Datagram            {get {return _datagram; } set            {_datagram = value; }}///<summary>//Get the socket object associated with the client session////</summary> public socket Clie            Ntsocket {get {return _clientsock; }} #endregion///<summary>//constructor///</summary>//<param N Ame= "Clisock" > Session using the Socket connection </param> public session (socket Clisock) {_clientsock = Cliso        ck }///<summary>///closed session///</summary> public void Close () {//            Turn off acceptance and transmission of data _clientsock.shutdown (Socketshutdown.both);        Cleanup resources _clientsock.close (); }    }

Event class
Class Asynceventargs:eventargs {///<summary>////        </summary>        Public string _msg;        Public Session _sessions;        <summary>///whether the///        </summary> 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;        }    }

The next time the socket version of the asynchronous client code is mended

C # Asynchronous socket TCP Server implementation

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.