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//</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" >< ;/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///</SUMMARY> 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///</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 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///< ;/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)!