Communication Programming PC software implementation (socket) -- Second

Source: Internet
Author: User

I don't talk much about this nonsense. I just need to go to the code.

First, the exceptions in the communication process are not processed (except for connection exceptions), and are controlled by timeout and retransmission.

 

1. Obtain the socket connection class timeoutsocket

 

Public class timeoutsocket {Private Static bool isconnectionsuccessful = false; // whether the connection is successful private static exception socketexception; Private Static manualresetevent timeoutobject = new manualresetevent (false); public static socket connect (IPaddress, int port, int timeoutmsec) {timeoutobject. reset (); // set the event to a non-terminating State, blocking the thread socketexception = NULL; socket temp = new socket (addressfamily. internetwor K, sockettype. stream, protocoltype. TCP); // asynchronously connects temp. beginconnect (New ipendpoint (IPaddress, port), new asynccallback (callbackmethod), temp); If (timeoutobject. waitone (timeoutmsec, false) {// If (isconnectionsuccessful) {return temp ;} else {Throw new timeoutexception ("failed to connect to the remote host! Check whether the network connection is smooth. ") ;}} Else {// close the connection and release all related resources temp. Close (); throw new timeoutexception (" connection timed out! Check whether the network connection is smooth. ");}} /// <Summary> // callback function after the asynchronous connection is successful /// </Summary> /// <param> </param> Private Static void callbackmethod (iasyncresult asyncresult) {try {isconnectionsuccessful = false; Socket Client = asyncresult. asyncstate as socket; // end a pending asynchronous connection request client. endconnect (asyncresult); isconnectionsuccessful = true;} catch (exception ex) {isconnectionsuccessful = false; socketexception = ex;} finally {// allow other threads to continue timeoutobject. set ();}}}

 

2. Communication variables (constants)

 

Private const int connecttimeout = 6000; // connection timeout, in MS, private byte [] DATA = new byte [1024]; // receives the byte array private int recvsize = 1024; // The number of received data is Private Static int XH = 1; // command serial number sent // The following two class libraries convertlibrary and dealprotocoldata are my encapsulated class libraries, in the future, convertlibrary convertdata = new convertlibrary () will be provided one by one; // The data can be converted to support dealprotocoldata = new dealprotocoldata (); // The Protocol results will be processed as required

 

Iii. Delegation

 

Delegation is essentially a pointer to a function and a class.

Delegate void dealrecvmsghandler (string Str); // used to process received data

 

The above sentence is decompiled with ildasm as follows:

 

It can be seen that the system generates its constructor by default (. Ctor is a constructor), as well as the member functions begininvoke, endinvoke, and invoke. The custom delegate inherits from system. multicastdelegate (extends can be seen in decompilation ).

 

 

Iv. asynchronous data receiving callback function ()

 

/// <Summary> /// receives data callback asynchronously /// </Summary> /// <param> </param> private void upload data (iasyncresult IAR) {socket remote = (socket) IAR. asyncstate; int Recv = 0; try {Recv = remote. endreceive (IAR); // exception: the remote host forces an existing connection to be closed} catch {} string tempstr = convertdata. bytetohex (data, Recv); // The byte array is converted into a hexadecimal if (tempstr. length> 0) {// dealrecvmsg data processing function dealrecvmsghandler handler = new dealrecvmsghandler (dealrecvmsg); handler. invoke (tempstr); // synchronous data processing} else {// due to the use of a third-party serial port to the network port module, sometimes it will receive a blank situation, then continue to receive try {remote. beginreceive (data, 0, recvsize, socketflags. none, new asynccallback (temporary data), publiccommunication. client);} catch {}}}

 

5. asynchronous data sending callback function (senddata)

 

/// <Summary> /// asynchronous data sending callback /// </Summary> /// <param> </param> private void senddata (iasyncresult IAR) {socket remote = (socket) IAR. asyncstate; try {int send = remote. endsend (IAR); currentsendedorderdate = datetime. now; // record the next sending time. If (listenertimer. enabled = false) // listenertimer is used to reissue listenertimer upon timeout. enabled = true; currentsendedorderenum = getsendedordertype (sendmsg); // get the sent command type currentsendedorderxh = getsendedorderxh (sendmsg); // get the sent command serial number // after sending, asynchronous remote reception. beginreceive (data, 0, recvsize, socketflags. none, new asynccallback (temporary data), publiccommunication. client);} catch {}}

 

 

 

6. receive data processing functions (determine the validity of the command and decide the next command. The specific data needs to be processed separately .)

 

Private void dealrecvmsg (string orgtempstr) {// here is a while loop. The condition of the loop is that the command length is greater than a minimum value. Each loop extracts the command according to the command length in the Command package, and use the remaining received commands for loop. // Because the communication follows a certain process, the command received here can determine the next command // roughly give the program while (orgtempstr. length> = 12) {try {string tempstr = orgtempstr. substring (0, Int. parse (convertdata. convertstring (orgtempstr. substring (2, 2), 16, 10) * 2); // extract a command orgtempstr = orgtempstr. substring (Int. parse (convertdata. convertstring (orgtempstr. substring (2, 2), 16, 10) * 2); // orgtempstr retain the remaining command // determine the Data Validity: the data received by the Protocol must be at least 12 characters long, and ensure that the received data is correct (Verification Code), gets The trxor () function is used to obtain the verification code, and the IF (tempstr. length> = 12 & dealprotocoldata. getstrxor (tempstr. substring (0, tempstr. length-2 )). equals (tempstr. substring (tempstr. length-2), stringcomparison. ordinalignorecase) {string workstate = tempstr. substring (8, 2); // obtain the instrument's working status string order = tempstr. substring (4, 2); // obtain the command word // if it is not the last command sent, the current data is discarded if (! Judgereceiveorderwithsendorder (Order, currentsendedorderenum) continue; // If (! (Int. parse (convertdata. convertstring (tempstr. substring (6, 2), 16, 10) = currentsendedorderxh) continue; currentsendedorderdate = datetime. minvalue; // After receiving the command, set the sending time of the command to the minimum value of 'datetime'. resendtimecount =-1; // The number of times of timeout resending // "00" should be defined as a constant, for ease of use, if "00" is changed to "FF", if (workstate. equals ("00", stringcomparison. ordinalignorecase) // The instrument works properly {If (Order. equals (protocolcontent. setparamscommandword, stringcomparison. ordi Nalignorecase) // sets the return value of the parameter command {// determines the next command to be sent sendmsg = ......;}...................... Byte [] MSG = convertdata. hextobyte (sendmsg); try {// send data publiccommunication asynchronously. client. beginsend (MSG, 0, MSG. length, socketflags. none, new asynccallback (senddata), publiccommunication. client); // process the sending sequence number. Ensure that the sending sequence number is between 1 and 256. XH = (XH + 1) %; If (XH = 0) XH = 1 ;} catch {}}

 

 

VII. Re-sending upon timeout

 

/// <Summary> /// command enumeration value /// </Summary> Public Enum orderenum {unknown = 0} Private Static string sendmsg = string. empty; // record the command Private Static orderenum currentsendedorderenum = orderenum. unknown; // record the type of the Command sent this time. Private Static int currentsendedorderxh =-1; // the serial number of the currently sent command: Private Static datetime currentsendedorderdate = datetime. minvalue; // The time when the last command was sent is private system. timers. timer listenertimer; // used for life monitoring Make the sent timer Private Static int resendtimecount =-1; // number of times the command is resent listenertimer = new system. timers. timer (25); listenertimer. elapsed + = new system. timers. elapsedeventhandler (listenertimer_elapsed); listenertimer. enabled = false; private void listenertimer_elapsed (Object sender, system. timers. elapsedeventargs e) {If (currentsendedorderdate! = Datetime. minvalue) // {double timeinterval = (datetime. now-currentsendedorderdate ). totalmilliseconds; If (timeinterval> = 1000) // resend {resendtimecount ++; If (resendtimecount> = 3) {// timeout processing ........ Return;} // if the request has not timed out three times, resend sendmsgwhentimeout (sendmsg );}}}

 

8. Handling after communication ends or timeout

 

When there is no communication, the client is closed and the server cannot detect the connection. Therefore, when I do this, the connection will be closed and left blank after a communication ends or times out.

private void WhenCommunicateOver(){listenerTimer.Enabled = false;try            {                PublicCommunication.client.Close();            }            catch { }            finally            {                PublicCommunication.client = null;            }}

 

9. Try three connections

 

Private void StartCommunication () {int connecttime = 0; do {try {publiccommunication. client = timeoutsocket. connect (IPaddress. parse (publicmodel. instrumentip), publicmodel. instrumentport, connecttimeout); break;} catch (exception EC) {connecttime ++; publiccommunication. client = NULL; If (connecttime> = 3) {whencommunicateover (); lock (whethershowerrormsg) {If (! (Bool) whethershowerrormsg) {MessageBox. show (this, EC. message, "system prompt", messageboxbuttons. OK, messageboxicon. error); whethershowerrormsg = true;} application. doevents (); Return ;}}while (connecttime <4 );}

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.