AForge.Robotics.Surveyor.SRV1.CommunicationThread C# (CSharp) Method

CommunicationThread() private method

private CommunicationThread ( ) : void
return void
        private void CommunicationThread( )
        {
            bool lastRequestFailed = false;

            while ( !stopEvent.WaitOne( 0, false ) )
            {
                // wait for any request
                requestIsAvailable.WaitOne( );

                while ( !stopEvent.WaitOne( 0, false ) )
                {
                    // get next communication request from queue
                    CommunicationRequest cr = null;

                    lock ( communicationQueue )
                    {
                        if ( communicationQueue.Count == 0 )
                            break;
                        cr = communicationQueue.Dequeue( );
                    }

                    try
                    {
                        // try to reconnect if we had communication issues on the last request
                        if ( lastRequestFailed )
                        {
                            Reconnect( );
                            lastRequestFailed = false;
                        }

                        if ( cr.Request[0] != (byte) 'I' )
                        {
                            // System.Diagnostics.Debug.WriteLine( ">> " +
                            //    System.Text.ASCIIEncoding.ASCII.GetString( cr.Request ) );
                        }

                        // send request
                        socket.Send( cr.Request );

                        // read response
                        if ( cr.ResponseBuffer != null )
                        {
                            int bytesToRead = Math.Min( readSize, cr.ResponseBuffer.Length );

                            // receive first portion
                            cr.BytesRead = socket.Receive( cr.ResponseBuffer, 0, bytesToRead, SocketFlags.None );

                            // check if response contains image
                            if ( ( cr.BytesRead > 10 ) &&
                                 ( cr.ResponseBuffer[0] == (byte) '#' ) &&
                                 ( cr.ResponseBuffer[1] == (byte) '#' ) &&
                                 ( cr.ResponseBuffer[2] == (byte) 'I' ) &&
                                 ( cr.ResponseBuffer[3] == (byte) 'M' ) &&
                                 ( cr.ResponseBuffer[4] == (byte) 'J' ) )
                            {
                                // extract image size
                                int imageSize = System.BitConverter.ToInt32( cr.ResponseBuffer, 6 );

                                bytesToRead = imageSize + 10 - cr.BytesRead;

                                if ( bytesToRead > cr.ResponseBuffer.Length - cr.BytesRead )
                                {
                                    // response buffer is too small
                                    throw new IndexOutOfRangeException( );
                                }

                                // read the rest
                                while ( !stopEvent.WaitOne( 0, false ) )
                                {
                                    int read = socket.Receive( cr.ResponseBuffer, cr.BytesRead,
                                        Math.Min( readSize, bytesToRead ), SocketFlags.None );

                                    cr.BytesRead += read;
                                    bytesToRead  -= read;

                                    if ( bytesToRead == 0 )
                                        break;
                                }
                            }
                            else
                            {
                                // commenting check for new line presence, because not all replies
                                // which start with '##' have new line in the end.
                                // this SRV-1 text based protocol drives me crazy.

                                /*
                                if ( ( cr.BytesRead >= 2 ) &&
                                     ( cr.ResponseBuffer[0] == (byte) '#' ) &&
                                     ( cr.ResponseBuffer[1] == (byte) '#' ) )
                                {
                                    int bytesChecked = 2;

                                    while ( cr.BytesRead != cr.ResponseBuffer.Length )
                                    {
                                        // ensure we got end of line for variable length replies
                                        bool endLineWasFound = false;

                                        for ( int n = cr.BytesRead - 1; bytesChecked < n; bytesChecked++ )
                                        {
                                            if ( ( ( cr.ResponseBuffer[bytesChecked]     == '\n' ) &&
                                                   ( cr.ResponseBuffer[bytesChecked + 1] == '\r' ) ) ||
                                                 ( ( cr.ResponseBuffer[bytesChecked]     == '\r' ) &&
                                                   ( cr.ResponseBuffer[bytesChecked + 1] == '\n' ) ) )
                                            {
                                                endLineWasFound = true;
                                                break;
                                            }
                                        }

                                        if ( ( endLineWasFound ) || stopEvent.WaitOne( 0, false ) )
                                            break;

                                        // read more
                                        bytesToRead = Math.Min( readSize, cr.ResponseBuffer.Length - cr.BytesRead );

                                        cr.BytesRead += socket.Receive( cr.ResponseBuffer, cr.BytesRead,
                                            bytesToRead, SocketFlags.None );
                                    }
                                }
                                */
                            }

                            // check if there is still something to read
                            // because of small buffer given by user
                            if ( socket.Available != 0 )
                            {
                                DiscardIncomingData( socket, stopEvent );
                            }


                            // System.Diagnostics.Debug.WriteLine( "<< (" + cr.BytesRead + ") " +
                            //     System.Text.ASCIIEncoding.ASCII.GetString( cr.ResponseBuffer, 0, Math.Min( 5, cr.BytesRead ) ) );
                        }
                        else
                        {
                            // read reply and throw it away, since nobody wants it
                            DiscardIncomingData( socket, stopEvent );
                        }
                    }

                    catch ( IndexOutOfRangeException )
                    {
                        cr.BytesRead = -2; // too small buffer
                    }
                    catch
                    {
                        if ( lastRequestFailed )
                        {
                            // wait a bit if we have 2 consequent failures
                            Thread.Sleep( 500 );
                        }

                        lastRequestFailed = true;
                        cr.BytesRead = -1; // communication failure
                    }
                    finally
                    {
                        // signal about available response to the waiting caller
                        if ( ( stopEvent != null ) && ( !stopEvent.WaitOne( 0, false ) ) && ( cr.ResponseBuffer != null ) )
                        {
                            lastRequestWithReply = cr;
                            replyIsAvailable.Set( );
                        }
                    }
                }
            }
        }