C # common methods for reading and writing socket

Source: Internet
Author: User
Assume that the message header is 16byte0-3 message header ID 4-7 message body length 8-15 CRC verification code
Public class streamhelper {# region converts a message into a byte array containing the message header /// <summary> /// converts the message into a byte array containing the message header /// </Summary> /// <Param name = "stream"> </param> /// <Param name = "message"> </param> /// <returns> </returns> public static byte [] getwrappedmessage (Google. protocolbuffers. iMessage message) {byte [] buff = message. tobytearray (); CRC32 CRC32 = new CRC32 (); crc32.update (buff); memorystream MS = new memorystream (); BYT E [] Tag = bitconverter. getbytes (constants. tag); byte [] Len = bitconverter. getbytes (buff. length); byte [] CRC = bitconverter. getbytes (crc32.value); Ms. write (TAG, 0, Tag. length); // write the header Ms. write (Len, 0, Len. length); // write the message length in ms. write (CRC, 0, CRC. length); // write the CRC32 value Ms. write (buff, 0, Buff. length); byte [] result = Ms. toarray (); Ms. close (); return result ;}# endregion # region writes the message to the stream // <summary> /// Write a message to a stream /// </Summary> /// <Param name = "stream"> </param> /// <returns> </returns> Public static void writetostream (networkstream stream, google. protocolbuffers. iMessage message) {byte [] buff = message. tobytearray (); CRC32 CRC32 = new CRC32 (); crc32.update (buff); byte [] Tag = bitconverter. getbytes (constants. tag); byte [] Len = bitconverter. getbytes (buff. length); byte [] CRC = bitconverter. getbytes (Cr C32.value); stream. write (TAG, 0, Tag. length); // write the header stream. write (Len, 0, Len. length); // write the message length stream. write (CRC, 0, CRC. length); // write the CRC32 Value Stream. write (buff, 0, Buff. length );} # endregion # region writes a message to socket /// <summary> /// write the message to socket /// </Summary> /// <Param name = "socket"> </param> // <returns> </returns> Public static void writetosocket (Socket socket, google. protocolbuffers. iMessage mess Age) {byte [] buff = message. tobytearray (); CRC32 CRC32 = new CRC32 (); crc32.update (buff); byte [] Tag = bitconverter. getbytes (constants. tag); byte [] Len = bitconverter. getbytes (buff. length); byte [] CRC = bitconverter. getbytes (crc32.value); socket. sendbuffersize = constants. headsize + buff. length; socket. send (TAG); // write the header socket. send (LEN); // write the message length socket. send (CRC); // write the CRC32 value socket. send (buff );} # Endregion # region reads all bytes from networkstream /// <summary> /// reads all bytes from networkstream /// </Summary> /// <Param name = "stream "> </param> // <returns> </returns> Public static byte [] readallbytes (networkstream Stream) {byte [] Head = new byte [constants. headsize]; If (stream. read (Head, 0, constants. headsize )! = Constants. headsize) // The transmission header is 16 bits. Only {return NULL;} headinfo = new headinfo (head); If (headinfo. Tag! = Constants. tag) // incorrect header {return NULL;} byte [] buff = new byte [headinfo. len]; int size = math. min (buff. length, 4096); // The maximum number of bytes read at a time. Int offset = 0; do {size = math. min (size, headinfo. len-offset); offset + = stream. read (buff, offset, size); If (offset = headinfo. len) // receives the specified length {CRC32 CRC32 = new CRC32 (); crc32.update (buff); If (crc32.value = headinfo. crc32value) // verify CRC32 {return Buff; }}} While (stream. dataavailable); log. errorformat ("client request failed: Offset {0}, head Len {1}", offset, headinfo. len); return NULL ;} # endregion # region reads all bytes from the socket /// <summary> /// reads all bytes from the socket /// </Summary> /// <Param name = "socket"> </param> /// <returns> </returns> Public static byte [] readallbytes (Socket socket) {byte [] Head = new byte [constants. headsize]; byte [] result = NULL; socketerror Error = Socketerror. success; int maxrepeat = 5; int got = 0; int repeat = 0; do // read the header {got ++ = socket. receive (Head, got, constants. headsize-got, socketflags. none, out error); If (got = constants. headsize | repeat> maxrepeat) // if the request is received completely or repeatedly for 10 times, {break;} else if (got = 0) // The number of times the Data repeat cannot be obtained {+ + repeat;} while (error = socketerror. success); If (got! = Constants. headsize) // verify the header length {log. error ("Incorrect head length"); return NULL;} headinfo = new headinfo (head); If (headinfo. tag! = Constants. tag) // the header is incorrect {log. errorformat ("head. tag incorrect ({0}, actual {1}) ", constants. tag, headinfo. tag); return NULL;} result = new byte [headinfo. len]; repeat = 0; got = 0; do // read the message body {got + = socket. receive (result, got, result. length-got, socketflags. none, out error); If (got = result. length | repeat> maxrepeat) // The {break;} else if (got = 0) is still not received if it has been received completely or repeated for 10 times) // The number of times the Data repeat cannot be obtained {+ + repeat ;}} While (error = socketerror. Success); If (got! = Result. length) // verification length {log. errorformat ("the length is incorrect ({0}, actually {1})", result. length, got); return NULL;} CRC32 CRC32 = new CRC32 (); crc32.update (result); If (crc32.value! = Headinfo. crc32value) // verify CRC32 {log. errorformat ("CRC verification failed ({0}, actual {1})", headinfo. crc32value, crc32.value); return NULL;} return result ;}# endregion # region asynchronously receives socket data (for testing) /// <summary> /// asynchronously receives socket data /// </Summary> /// <Param name = "socket"> </param> /// <returns> </returns> Public static byte [] receivedata (Socket socket) {receiveobject state = new receiveobject () {client = socket}; SOC Ket. beginreceive (state. buffer, 0, state. buffer. length, socketflags. none, new asynccallback (readcallback), State); State. receivedone. waitone (socket. receivetimeout); // timeout setting byte [] Head = new byte [constants. headsize]; State. stream. seek (0, seekorigin. begin); If (state. stream. read (Head, 0, constants. headsize )! = Constants. headsize) // read the header {return NULL;} headinfo = new headinfo (head); If (headinfo. Tag! = Constants. Tag) // the header is incorrect {return NULL;} If (State. Stream. Length-16! = Headinfo. len) // verification length {return NULL;} // state. stream. seek (16, seekorigin. begin); byte [] result = new byte [State. stream. length-16]; State. stream. read (result, 0, result. length); // read the message body CRC32 CRC32 = new CRC32 (); crc32.update (result); If (crc32.value = headinfo. crc32value) // verify CRC32 {return result;} return NULL;} // <summary> // synchronously receives the object // </Summary> private class receiveobject: idisposable {public Socket Client; Public byte [] buffer = new byte [4096]; public system. io. memorystream stream = new system. io. memorystream (); public system. threading. manualresetevent receivedone = new system. threading. manualresetevent (false); Public void dispose () {This. stream. close ();}} /// <summary> /// read callback /// </Summary> /// <Param name = "Ar"> </param> Private Static void readcallback (iasyncresult ar) {receiveobject state = (receiveobject) ar. asyncstate; int bytesread = state. client. endreceive (AR); If (bytesread> 0) {try {state. stream. write (state. buffer, 0, bytesread); State. client. beginreceive (state. buffer, 0, state. buffer. length, socketflags. none, new asynccallback (readcallback), State);} catch (exception ex) {log. error (ex. message); State. receivedone. set () ;}} else {state. receivedone. set (); // state. client. endreceive (AR) ;}# endregion}

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.