C#socket Communications under the. NET Platform

Source: Internet
Author: User

The C#socket communication under the. NET platform (above) introduces the basic principle of socket communication and the most fundamental means of communication. This article on this basis on the socket communication often encountered problems to do a simple summary, are some small problems in the project, take here to facilitate the next use, at the same time, when using the socket has a few problems in the colleagues have a superficial suggestion. Please put forward the deficiencies, thank you.

This article mainly describes:

1. Handshake establishment in normal communication

2, one-to-many communication

3. Send and receive data format conversion

4. Release of resources

5. Open and maintain service monitoring

1, shake hands to establish a normal communication channel

The project needs to establish a stable channel between the two parties (assuming a host computer, a subordinate machine) to communicate. The specific operation of this project is: the host computer as a server, the lower machine as a client, at the same time to develop a communication protocol. The host computer first opens the listening wait to establish the channel, the next computer actively connects the host computer after sending the information to the host computer, the host computer according to the communication protocol to send data to the next machine, at this time the channel has been established. But for the sake of insurance (at the same time three handshake), the client sends the data again to the host computer to inform the channel is established.

2, one-to-many communication

Project demand is a host computer multiple lower machine, which determines the host computer as the server side, the next computer as a client active connection server. There is only one socket channel in a single communication, so neither the host computer nor the lower computer will have data hair when sending and receiving data. A one-to-many means that the host computer and the next opportunity to establish a plurality of channels, so when sending data need to record which lower computer in which socket channel, for logical processing. The process of handling one-to-many communication in this article is:

1) First set up a dialog class session:

public class Session    {public        Socket clientsocket {get; set;} The client's socket public        string ip;//the IP public Session of the client        (Socket clientsocket)        {this            . Clientsocket = Clientsocket;            This. IP = Getipstring ();        }        public string getipstring ()        {            string result = ((IPEndPoint) clientsocket.remoteendpoint). Address.tostring ();            return result;        }    }

2) When the server socket is listening:

 IPEndPoint loaclendpoint = new IPEndPoint (Ipaddress.any, Port);            Socketlister = new Socket (AddressFamily.InterNetwork, SocketType.Stream, protocoltype.tcp);            Socketlister.bind (Loaclendpoint);                try {socketlister.listen (maxconnection);                    while (isrunning) {clientsocket = Socketlister.accept ();                    Save Socket Session NewSession = new session (Clientsocket);                    Lock (Sessionlock) {Sessiontable.add (Newsession.ip, newsession);                    } socketconnection socketconnection = new SocketConnection (clientsocket);             Socketconnection.receivedatagram ();//Receive Data}} catch (SocketException ex) { 



//Declaration

Public Hashtable sessiontable = new Hashtable ();//INCLUDE client session

Private Object Sessionlock = new Object ();

To facilitate understanding, the entire service-side socket is set up on top.

3) Send data to different clients

Hashtable ht = serversocket.sessiontable;            foreach (Session session in HT. Values)            {                if (session). IP = = "127.0.0.1")//example                {                    socketconnection socketconnection = new SocketConnection (session. Clientsocket);                    String str = "C300010002D2";                    byte[] sendbytes = Strtohexbyte (str);                    Socketconnection.send (sendbytes);                }                           }

The SocketConnection class has been used several times and is written in the following:

public class Socketconnection:idisposable {public ServerSocket Server {get; set;}        Public byte[] Msgbuffer = null;        private int totallength = 0;        public int currentbufferlength;        Private Socket _clientsocket = null;        Public Socket Clientsock {get{return this._clientsocket;}        Public Socketconnectiontype Type {get; private set;} #region Constructor public socketconnection (serversocket server, Socket sock) {this.            Server = server;            This._clientsocket = sock; This.        Type = Socketconnectiontype.server;            } public SocketConnection (Socket sock) {this._clientsocket = sock; This.        Type = socketconnectiontype.client; } #endregion #region Events public socketconnectiondelegate OnConnect = null;//whether to connect public so Cketconnectiondelegate Onlostconnect = null;//Interrupt Connection public receivedatadelegate Onreceivedata = null;//Receive data #endregion #region connect public void Connect (IPAddress IP, int port) {this. Clientsock.beginconnect (IP, port, Connectcallback, this.)        Clientsock); } private void Connectcallback (IAsyncResult ar) {try {Socket handler = (Socket) ar.                asyncstate; Handler.                EndConnect (AR);                if (OnConnect! = null) {OnConnect (this);            } receivedatagram (); } catch (SocketException ex) {}} #endregion #region Send pu        Blic void Send (String data) {Send (System.Text.Encoding.UTF8.GetBytes (data)); } public void Send (byte[] bytedata) {try {int length = Bytedata.lengt                H                Byte[] head = bitconverter.getbytes (length); byte[] data = New Byte[head.                Length + bytedata.length]; Array.copy (head, data, head).                Length); Array.copy (bytedata, 0, data, head.                Length, bytedata.length); This. Clientsock.beginsend (data, 0, data. Length, 0, New AsyncCallback (Sendcallback), this.            Clientsock); } catch (SocketException ex) {}} private void Sendcallback (IAsyncResult a R) {try {socket handler = (socket) ar.                asyncstate; Handler.            EndSend (AR); } catch (SocketException ex) {}} #endregion #region Receivedatagra            M public void Receivedatagram () {Socketstateobject state = new Socketstateobject ();            State.worksocket = _clientsocket; _clientsocket.beginreceive (state.buffer, 0, socketstateobject.buffersize, 0, New AsyncCallback (ReceiveCallback),        State); } privatevoid ReceiveCallback (IAsyncResult ar) {socketstateobject state = (socketstateobject) ar.            asyncstate;            Socket handler = State.worksocket; if (handler. Connected) {try {State.bytesread = handler.                    EndReceive (AR); if (State.bytesread > 0) {ondatarecivedcallback (State.buffer, State.bytesrea                        D);                        Array.clear (state.buffer, 0, state.buffer.Length);                        State.bytesread = 0; Handler.                    BeginReceive (state.buffer, 0, socketstateobject.buffersize, 0, New AsyncCallback (ReceiveCallback), state);                        } else {//if (ondisconnect! = null)                        {//OnDisconnect (this);                    } Dispose (); }                }                catch (SocketException ex) {}}} private void ReceiveCallBack00 (                IAsyncResult ar) {try {int REnd = _clientsocket.endreceive (AR);                    if (REnd > 0) {ondatarecivedcallback (Msgbuffer, REnd);                    Array.clear (msgbuffer, 0, msgbuffer.length);                    REnd = 0;                _clientsocket.beginreceive (msgbuffer, 0, msgbuffer.length, 0, New AsyncCallback (ReceiveCallBack00), null);                        } else {if (onlostconnect! = null) {                    Onlostconnect (this);                } Dispose (); }} catch (Exception ex) {}} private void Ondatarecivedcallbac         K (byte[] data, int length) {if (length > 0) {       if (this.                    Msgbuffer = = null) {byte[] bytelength = new Byte[4];                    Array.copy (data, ByteLength, 4);                    This.totallength = Bitconverter.toint32 (bytelength, 0); This.                    Msgbuffer = new Byte[this.totallength]; This.                currentbufferlength = 0;                    } if (This.totallength > 0) {int offset = 0;                    if (Currentbufferlength = = 0) {offset = 4; } if (length + this.) Currentbufferlength >= This.totallength + offset) {int len = This.totallengt                        H-currentbufferlength; Array.copy (data, offset, this.) Msgbuffer, this.                        Currentbufferlength, Len); byte[] tmp = this.                        Msgbuffer.clone () as byte[];  Onreceivedata (New MessageData (this, TMP));                      This.                        Msgbuffer = null; if (Length-len-offset > 0) {tmp = new Byte[length-len-offset                            ]; Array.copy (data, offset + len, tmp, 0, TMP.)                            Length); Ondatarecivedcallback (TMP, TMP.                        Length); }} else {array.copy (data, offset, THIS.M Sgbuffer, this.                        Currentbufferlength, Length-offset); This.                    Currentbufferlength + = Length-offset; }} else {}}} public void Dispose ( {try {this].                Clientsock.shutdown (Socketshutdown.both); This.                Clientsock.close (); This.                Server = null;               if (onlostconnect! = null)//{ Onlostconnect (this); }} catch {}} #endregion}

3. Processing data that needs to be sent and received

The project needs to be the host computer to obtain data for logical processing, and then through the TCP/IP protocol sent to the lower machine, the next computer in the receiving of data while sending confirmation information to the host computer. Project process, the host computer in the development process need to debug its sending data, receive data is successful, here with the help of usr-tcp232 gadgets. However, when it comes to a problem, the sending and receiving of the lower computer are all byte arrays, then how should the host computer send and receive the data? In the. NET Platform C#socket Communication (above), there is a server-side send and receive functions, send data when the string to be sent to a byte array, receive and then convert the byte array to 16 binary string. As follows:

The byte array is converted to a 16-character string, public-string        bytetohexstr (byte[] bytes)        {            string str = "";            if (bytes! = null)            {for                (int i = 0; i < bytes. Length; i++)                {                    str + = Bytes[i]. ToString ("X2");                }            }            return str;        }        Convert string to 16 binary byte array public        byte[] Strtohexbyte (string data)        {            data = data. Replace ("", "");            if (data. Length% 2)! = 0)            {                data + = ";            }            byte[] bytes = new Byte[data. LENGTH/2];            for (int i = 0; i < bytes. Length; i++)            {                 Bytes[i] = Convert. ToByte (data. Substring (i * 2,2), +);            }            return bytes;        }

4. Release of resources

The development project use platform is. NET, tool vs2010, language is C #, because. NET has a garbage collection mechanism, so the managed resources that are generated in real-world development are automatically released by the system. Developed using WinForm when doing this project, a problem was found in this process: the system that is running on the Close form form is not completely closed. The reason for the lookup should be that there are resources not being released. The source of the socket socket is the unmanaged resource, which indicates that the socket resource in the system has not been completely released. So write a resource release function:

public void Dispose ()        {            Try            {this                . Clientsocket.shutdown (Socketshutdown.both);                This. Clientsocket.dispose ();                This. Clientsocket.close ();                This. Clientsocket = null;            }            Catch            {            }        }

The function of the above functions is to release the resources generated by the socket, after the call to find that there is still this problem, after several debugging found that although the socket channel to generate the listener client resources to complete the release, the server side of the ServerSocket is not released, so there is the next function:

public void Closesocket ()        {            if (serversocket! = null)            {                serverSocket.SocketLister.Dispose ();                Serversocket.socketlister = null;                Serversocket.dispose ();//The last function called                serversocket = null;}        }

After the above function is completed, the resources generated by the socket socket are actually released and the system can be closed after the form is closed. This resource seems to have been released, but then the new problem arises:

When and where do you call the function that frees the resource?

Personal Simple view:

1) Call when system aborts

2) Called when the socket channel is interrupted

Add:

5. Open and maintain service monitoring

In the socket communication, the service side of the socket monitoring is actually need to open and maintain, only in this way to listen to the connected client at any time. Examples in projects:

private void Button1_Click (object sender, RoutedEventArgs e) {thread thread = new Thread (New Threadstar            T (StartServer)); Thread.        Start ();            }public void StartServer () {int port = Convert.ToInt32 (GetText (This.tbport));            String ipstr = GetText (THIS.TBSERVERIPSTR);                if (ServerSocket = = null) {ServerSocket = new ServerSocket (port);            Serversocket.start (IPSTR);//} else {MessageBox.Show ("Listener is turned on"); }}public void Start (String ipstr) {IPEndPoint localendpoint = new IPEndPoint (ipaddre Ss.            Any, Port);            IPEndPoint localendpoint = new IPEndPoint (Ipaddress.parse (IPSTR), Port);            Socketlister = new Socket (AddressFamily.InterNetwork, SocketType.Stream, protocoltype.tcp);            Socketlister.bind (Localendpoint); try {Socketlister.listen (maxconnection);                    while (isrunning) {clientsocket = Socketlister.accept ();                    Save Socket Session NewSession = new session (Clientsocket);                    Lock (Sessionlock) {Sessiontable.add (Newsession.ip, newsession);                    } socketconnection socketconnection = new SocketConnection (clientsocket);                Socketconnection.receivedatagram (); }} catch (SocketException ex) {}}

Explanation: Click the button to open a new thread, execute method Startserver,startserver Call method Start,start method using a dead loop to open and keep listening.

C#socket Communication (RPM) under the. NET Platform

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.