C # Network Programming series article (i) Socket implementation asynchronous TCP server

Source: Internet
Author: User

Opening

I because of the love of network programming, regular use of C # to write various types of servers (e.g TCP server, UDP server), but basically are engaged in play, there are a lot of web-based C # network programming articles, of course, I also refer to a lot of authors write articles. After reading this article will not be exported to find information.

This series of articles introduces asynchronous TCP servers implemented with sockets , synchronous TCP Servers , asynchronous UDP servers, synchronous UDP servers , and use Asynchronous TCP Servers , synchronous TCP Servers , asynchronous UDP servers, and synchronous UDP servers implemented by TcpListener and UdpClient.


Socket Asynchronous TCP Server

Believe that the people who have done network programming, this TCP is not a stranger, in C # Microsoft has helped us encapsulate a tcplistener and tcpclient these two classes, the implementation of the socket package, but it is actually not very useful, So we use the socket to implement an asynchronous TCP server.

In this article I only give the server-side code, the client code can look elsewhere, after all, I just to write a good server-side

Here is the code


Using system;using system.collections.generic;using system.linq;using system.text;using System.Net.Sockets;using System.net;namespace netframe.net.tcp.sock.asynchronous{//<summary>///socket-implemented asynchronous TCP Server//</summa  Ry> public class Asyncsockettcpserver:idisposable {#region fields///<summary>//        Maximum number of client connections allowed by the server program//</summary> private int _maxclient;        <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<asyncsocketstate> _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>////</summary> public int port {get; private set;}        <summary>////</summary> public Encoding Encoding {get; set;}        #endregion #region Constructors///<summary>//Async Socket TCP Server///</summary> <param name= "Listenport" > Listening ports </param> public asyncsockettcpserver (int listenport): This (Ipaddress.any, listenport,1024) {}//<summary>//asynchronous Socket TCP Server///&L t;/summary>//<param name= "localep" > Monitored endpoints </param> public asyncsockettcpserver (IPEndPoint l OCALEP): This (localep.address, localep.port,1024) {}//<summary>//Async so Cket TCP Server//&LT;/summary>//<param name= "localipaddress" > Listening IP address </param>//<param name= "Listenport" &G t; listening ports </param>///<param Name= "maxclient" > Maximum number of clients </param> public Asyncsockettcpserver (IP Address localipaddress, int listenport,int maxclient) {this.            Address = localipaddress; This.            Port = Listenport; This.            Encoding = Encoding.default;            _maxclient = maxclient;            _clients = new list<asyncsocketstate> ();        _serversock = new Socket (localipaddress.addressfamily, SocketType.Stream, protocoltype.tcp); } #endregion #region Method///<summary>///Start server//</summary> p ublic void Start () {if (!                isrunning) {isrunning = true; _serversock.bind (New IPEndPoint (this. Address, this.                Port));                _serversock.listen (1024); _serversock.beGinaccept (New AsyncCallback (handleacceptconnected), _serversock);         }}///<summary>//Start server///</summary>//<param name= "Backlog" > Maximum length of the pending connection sequence allowed by the server///</param> public void Start (int backlog) {if (!                isrunning) {isrunning = true; _serversock.bind (New IPEndPoint (this. Address, this.                Port));                _serversock.listen (backlog);            _serversock.beginaccept (New AsyncCallback (handleacceptconnected), _serversock);            }}///<summary>//Stop server///</summary> public void Stop () {                if (isrunning) {isrunning = false;                _serversock.close ();        TODO closes the connection to all clients}}///<summary>//Process Client connection///</summary> <param name= "AR" ></param> 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) {//c-todo trigger Event                Raiseotherexception (NULL);                    } else {asyncsocketstate state = new Asyncsocketstate (client); Lock (_clients) {_clients.                        ADD (state);                        _clientcount++; Raiseclientconnected (state); Triggers the client Connection event} state. Recvdatabuffer = new Byte[client.                    Receivebuffersize]; Start accepting data from the client. BeginReceive (state. Recvdatabuffer, 0, state. Recvdatabuffer.length, Socketflags.none, new AsyncCallback (handledatareceived), state); }//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) { Asyncsocketstate state = (asyncsocketstate) ar.                asyncstate; Socket client = state.                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) {//c-todo trigger event (Close client) close (state);                        Raiseneterror (state);                    Return //todo processing the data that has been read PS: Data in//c-todo trigger Data Receive event raisedatareceived (state) in recvdatabuffer of State; } catch (socketexception) {//c-todo exception handling Raiseneterr                or (state); Finally {//continues to receive the data client from the clients. BeginReceive (state. Recvdatabuffer, 0, state.                Recvdatabuffer.length, Socketflags.none, New AsyncCallback (handledatareceived), state); }}///<summary>//Send data///</summary>//<param name = "State" > Client session receiving Data </param>//<param name= "Data" > Packet </param> public void Send (Asyncs            Ocketstate state, byte[] data) {raisepreparesend (state); Send (state.        Clientsocket, data); }///<summary>///asynchronously sends data to the specified client///</summary>///Lt;param name= "Client" > Clients </param>//<param name= "Data" > Messages </param> public void Send (S Ocket 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);        Raisecompletedsend (NULL);        } #endregion #region Event///<summary>///connection to client established event///</summary> PuBlic event eventhandler<asyncsocketeventargs> clientconnected; <summary>//connection to client disconnected Event///</summary> public event Eventhandler<asyncsocketeve        Ntargs> clientdisconnected;        <summary>///Trigger Client Connection Events///</summary>//<param name= "state" ></param>            private void raiseclientconnected (Asyncsocketstate state) {if (clientconnected! = null)            {clientconnected (this, new Asyncsocketeventargs (state)); }}///<summary>//Trigger Client Connection Disconnect Event///</summary>//<param name= "client "></param> private void raiseclientdisconnected (Socket client) {if (clientdisconnected            ! = null) {clientdisconnected (this, new Asyncsocketeventargs ("Disconnected")); }}///<summary> received data events///&LT;/SUMMARY&GT        public event eventhandler<asyncsocketeventargs> DataReceived;                private void raisedatareceived (Asyncsocketstate state) {if (datareceived! = null) {            DataReceived (This, new Asyncsocketeventargs (state)); }}///<summary>///events before sending data///</summary> public event eventhandler<        Asyncsocketeventargs> Preparesend;        <summary>///trigger event before data is sent///</summary>//<param name= "state" ></param>                private void Raisepreparesend (Asyncsocketstate state) {if (preparesend! = null) {            Preparesend (This, new Asyncsocketeventargs (state)); }}///<summary>///Data Send complete Event///</summary> public event eventhandler<                Asyncsocketeventargs> Completedsend; <summary>///Trigger data sent Event///</summary>//<param name= "state" ></param> private void Raisecompletedsend (Asyncsocketstate St ATE) {if (completedsend! = null) {Completedsend (this, new Asyncsocketeventar            GS (state)); }}///<summary>//Network error events///</summary> public event Eventhandler<as        Yncsocketeventargs> Neterror;        <summary>///Trigger Network error events///</summary>//<param name= "state" ></param>                private void Raiseneterror (Asyncsocketstate state) {if (neterror! = null) {            Neterror (This, new Asyncsocketeventargs (state)); }}///<summary>///exception Event///</summary> public event Eventhandler<asyn        Csocketeventargs> otherexception; <summary>///Trigger Exception events///</summary>//<param name= "statE "></param> private void Raiseotherexception (asyncsocketstate state, String descrip) {i            F (otherexception! = null) {otherexception (this, new Asyncsocketeventargs (Descrip, state)); }} private void Raiseotherexception (Asyncsocketstate state) {Raiseotherexceptio        N (State, "");        #endregion #region Close//<summary>//Close a session with the client///</summary>            <param name= "State" > Client Session object that needs to be closed </param> public void close (Asyncsocketstate state) { if (state = null) {state.                Datagram = null; State.                Recvdatabuffer = null; _clients.                Remove (state);                _clientcount--; TODO triggers the Shutdown event state.            Close ();      }}///<summary>//Close all client sessions, and all client connections will be disconnected///</summary>  public void Closeallclient () {foreach (Asyncsocketstate client in _clients) {            Close (client);            } _clientcount = 0; _clients.        Clear (); } #endregion #region Release//<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) {                    TODO raiseotherexception (NULL);            }} disposed = true; }} #endregion}}


Event Argument class

Using system;using system.collections.generic;using system.linq;using system.text;namespace netframe.net.tcp.sock.asynchronous{//<summary>///Asynchronous Socket TCP Event parameter class////</summary> public Clas  s Asyncsocketeventargs:eventargs {///<summary>/////</summary> Public        String _msg;        <summary>///Client Status Package class////</summary> public asyncsocketstate _state;        <summary>///whether the///</summary> public bool ishandled {get; set;}            Public Asyncsocketeventargs (String msg) {this._msg = msg;        ishandled = false;            Public Asyncsocketeventargs (asyncsocketstate state) {this._state = state;        ishandled = false;            } public Asyncsocketeventargs (String msg, asyncsocketstate state) {this._msg = msg;            This._state = State; IsHanDled = false; }    }}


User State encapsulation

Using system;using system.collections.generic;using system.linq;using system.text;using System.Net.Sockets; namespace netframe.net.tcp.sock.asynchronous{//////<summary>///For the class used to store client state information in asynchronous socket TCP/</summar Y> public class Asyncsocketstate {#region Field///<summary>//Receive data buffer///&LT        ;/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 to session messages///</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 asyncsocketstate (socket clisock) {_CLIENTSOC        K = Clisock;            }///<summary>//Initialize data buffer///</summary> public void Initbuffer () { if (_recvbuffer = = null&&_clientsock!=null) {_recvbuffer=new byte[_clientsock.re            Ceivebuffersize]; }        }       <summary>///close session///</summary> public void Close () {//close            Acceptance and transmission of data _clientsock.shutdown (Socketshutdown.both);        Cleanup resources _clientsock.close (); }    }}

The above is the C # Network programming series (a) Socket implementation of asynchronous TCP server content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • 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.