C # Asynchronous socket

Source: Internet
Author: User

C # Asynchronous socket (BEGINXXXX) server code

Objective:

1, a recent maintenance of the company's old project, is the socket communication, mainly used to receive the IPC (client) sent up the snapshot image, during the period to maintain communications, monitoring data packets and processing. But see before the person wrote code personally feel not very suitable for themselves, so rewrite, but the project temporarily abandoned, in order to later can be convenient to use, but also convenient for more like me or the dregs of the programmer's people, record some experience. I still believe that words, sharing can progress faster

2, in fact, before I know about this thing very little, after all, to my understanding, in the domestic C # More is used to develop the site, so also in the online to see a lot of the code, I tried to copy and paste directly, found that a lot of people can not use the last to write to find the original is such a thing. So here also advise you not to do the hand party, through their own understanding to be able to transform the knowledge of others into their own capital

Start :

1, the Socket communication is divided into synchronous and asynchronous mode, the client is generally synchronous, asynchronous more for the service side. As for the difference between the two, many predecessors have already had the blog elaborated, I here put one of the links to help you understand: http://www.cnblogs.com/BLoodMaster/archive/2010/07/02/1769774.html. In case this link fails, I believe you will also find other resources

2, to do this socket communication, I think the key point is "data processing" rather than establish a link, but often a lot of people do not understand the difficulties encountered, such as socket close, drop packets, sticky bags and so on. The common practice is

2.1: Use buffers to store all the received byte arrays, then analyze the data to get a valid part.

2.2: The server and the client need to agree on the format of the message, in general, there must be at least "Data header identification", "data entity Length", "Data tail identification", so as to better handle the data, otherwise you can hardly define which piece of data is what you want.

2.3: Data analysis must be less the use of string or character disassembly, because it is likely to get the length is wrong (there are many empty bytes, or the encoding decoding problem causes the string length inconsistent), so be sure to use a byte array to handle, through a well-agreed encoding decoding format, Find the location where the identity is located for data disassembly. "For example: the client and the server connection need to check identity information, so the special encryption of a string to re-encode sent, after the server received the data if the first compiled into a string and then get the password to byte[], the length is likely to be different from the previous record." However, it is more convenient to disassemble the message header by string.

3, the common problem when establishing a connection is that there is no loop to receive the client message caused the socket to be released, or only to accept a few messages to the client after the stop, I have encountered this problem, So the key to establishing a connection is the recursive loop invocation of the two methods of BeginAccept and BeginReceive

4, the next is the paste code, here only the server, the client I have not done after the completion will be sent up, the entry function is open, the main method all here, as to the auxiliary function (such as to obtain an IP address, check whether the port is occupied, get send message you can find it yourself, After all, these are already many predecessors open source)

4.1: Because I am just a slag wild program ape, if you have any different views please put forward, communication is also a good way to improve

4.2: If you feel useful, or hope to be able to recommend, so that more new people to see, so that we can learn from each other, nor waste my effort to write a blog, thank you

4.3: I would like to have the great God to tell me the lack of place, because I know that the code is not well written ~

public void Create_server_socket () {Thread th_server = null; string result = String.            Empty; try {socketserver = new Socket (AddressFamily.InterNetwork, SocketType.Stream, protocoltype.tcp)                ;                IPAddress IP = Pubilc.Helper.Computer.GetIPv4 ();                IPEndPoint point = new IPEndPoint (IP, this._port);                Socketserver.bind (point);                Socketserver.listen (This._listen); Th_server = new Thread (() = {if (this._isrunning) Socketserv Er.                    BeginAccept (Acceptcallback, socketserver);                else Close_server_socket ();                }); Th_server.                IsBackground = true; Th_server.            Start (); } catch (Exception ex) {if (th_server. IsAlive) Th_server.                Abort (); Showlog (ex.  Message);          }; } public void Close_server_socket () {if (socketserver! = null) {Socke            Tserver.close (); }} void Acceptcallback (IAsyncResult ar) {socket socketserver = (socket) ar.            asyncstate;                try {Socket socketaccept = socketserver.endaccept (AR);                Dynamicbuffer state = new Dynamicbuffer ();                State.worksocket = socketaccept; Socketaccept.beginreceive (state. Buffers, 0, state.            Buffers.length, Socketflags.none, ReceiveCallback, state);                } catch (Exception ex) {Loghelper.writelog (typeof (Sockethelper_server), ex); Showlog ("Acceptcallback" + ex.            Message); } finally {if (this._isrunning) socketserver.beginaccept (ACCEPTCA            Llback, Socketserver); }} void ReceiveCallback (IAsyncResult ar) {string sendmsg = string.            Empty; Dynamicbuffer state = (dynamicbuffer) ar.            asyncstate;            Socket socketaccept = State.worksocket;                try {int len = socketaccept.endreceive (AR); if (Len > 0) {state.                Writbuffer (); } else {sendmsg=domsg.checkconnection (SocketAccept.RemoteEndPoint.ToStri                    Ng ()); if (!string.                        IsNullOrEmpty (sendmsg)) {byte[] buffer = Encoding.Default.GetBytes (sendmsg);                    State.sb.AddRange (buffer);                        } else {Socketaccept.shutdown (socketshutdown.both);                    Socketaccept.close (); }}} catch (Exception ex) {Loghelper.writelOG (typeof (Sockethelper_server), ex); Showlog ("ReceiveCallback" + ex.            Message);                    } finally {if (this._isrunning) {try                        {Thread th_send = null;                            Th_send = new Thread (() = {Send (ref state); Th_send.                        Abort ();                        }); Th_send.                        IsBackground = true; Th_send.                        Start (); Socketaccept.beginreceive (state. Buffers, 0, state.                    Buffers.length, Socketflags.none, ReceiveCallback, state); } catch (Exception ex) {Showlog (ex.                        Message);                    Loghelper.writelog (typeof (Ipcserverdo), ex);       }}}} void Send (ref dynamicbuffer State) {byte[] buffer = NULL; String sendmsg = String.            Empty;            Socket socketaccept = State.worksocket;            dictionary<string, byte[]> data; State.            Getalldata (out data); if (data.                 Count > 0) {sendmsg = DOMSG.ACCEPTFROMIPC (socketAccept.RemoteEndPoint.ToString (), ref data); if (!string.                    IsNullOrEmpty (sendmsg)) {buffer = Encoding.Default.GetBytes (Sendmsg.tochararray ()); Socketaccept.beginsend (buffer, 0, buffer.)                Length, Socketflags.none, Sendcallback, socketaccept);            } Send (ref state); }} void Sendcallback (IAsyncResult ar) {socket socketaccept = (socket) ar.            asyncstate;            try {int sendbytes = socketaccept.endsend (AR); } catch (Exception ex) {Loghelper.writelog (typeof (Sockethelper_servER), ex); }        }

4, the following is the state object class, in fact, this is equivalent to buffer, put things here to save, including the socket object, in fact, it is useful is the above declaration part and the constructor, as for the following writing method and data disassembly, buffer cleanup method I feel to be improved, Because in this way I am receiving a picture of about 500KB 10 seconds to return the results (the entire logic process to complete and send data time), this is not acceptable, so the following data processing methods, we have a matter of opinion, according to their own needs to find their own suitable method, here just provide ideas

<summary>///Cycle queue///</summary>//<typeparam name= "T" ></typeparam> public clas s Dynamicbuffer {//<summary>//Buffer size///</summary> public int buffersize       {get; set;}        <summary>///Communication object///</summary> public Socket worksocket {get; set;}        <summary>//buffer////</summary> public byte[] buffers {get; set;}        <summary>///Storage area///</summary> public list<byte> sb;            Public Dynamicbuffer () {this.buffersize = 1024 *64;            THIS.SB = new list<byte> (); This.        buffers = new Byte[buffersize];            }///<summary>///buffer data is put into storage///</summary> public void Writbuffer () {            int endposition = 0;            byte[] buffer;            int len = 0; for (endposition = This. Buffers.length-1; Endposition >= 0; endposition--) {//Because there is a lot of empty bytes in the discovery data, the reverse delete if (this) is performed here from the last start.            Buffers[endposition]! = (byte) '% ') break;            Len = endposition + 1;//because it is taking length, not position, so here +1 buffer = new Byte[len]; Array.copy (this.            buffers, 0, buffer, 0, Len);            This.sb.AddRange (buffer); This.        buffers = new Byte[buffersize];            }//Returns the specified length of byet[] data, and will clean the corresponding storage area public void Getalldata (out dictionary<string, byte[]> data) {            int datalength = 0;            Datalength = getallacceptmsg (out data);            if (datalength > 0) {clearlist (datalength); }}//Clean up the contents of the store already sent and empty packet data so that the next time you receive using private void clearlist (int datalength) {THIS.SB .        RemoveRange (0, datalength);       }///<summary>//Determine if the storage area accepts the full package//and the complete package is stored, disassembled </summary>//<returns> length of a single valid data </returns> private int getallacceptmsg (out Dictionar            y<string, byte[]> data) {int datalength=0;            int contentlength = 0;            int newlineposition = 0; string title = String.            Empty; String arr_msg = String.            Empty;            byte[] buffer = This.sb.ToArray ();            data = new dictionary<string, byte[]> (); try {newlineposition = statichelp.search (buffer, Encoding.Default.GetBytes ("\r\n\r\n\r\n"), FAL SE);//Find the position of the line break if (Newlineposition > 0) {arr_msg = Encoding.UTF8.GetSt                    Ring (buffer);                    ContentLength = Convert.ToInt32 (Commonhelper.getstrbyregex (arr_msg, "Content-length:", "\ r \ n")); int datalen = buffer.                    Length-newlineposition; if (Datalen >= contentlength) {title= Arr_msg.                        Split (new string[] {"\r\n\r\n\r\n"}, Stringsplitoptions.none) [0] + "\ r \ n";                        byte[] PostData = new Byte[contentlength]; if (ContentLength > 0) buffer.blockcopy (Buffer, newlineposition, PostData, 0, ContentLength)                        ; Data.                        ADD (title, postdata);                    Datalength = newlineposition + contentlength;                }} else {datalength = 0;            }} catch (Exception ex) {Loghelper.writelog (typeof (Ipcserverdo), ex);        } return datalength;         }    }

Category: C#socket communication

C # Asynchronous socket

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.