Android socket does not come out of the while, why?

Asked

Viewed 51 times

0

After sending the event I have to close the program to send another event through the socket. I realized that it is not closing, gets stuck in the while paps go through the publichProgress(response); Actually when you walk into buffData = is.read( buff, 0, 2048 ); he pauses the thread.

SOCKET

   protected Boolean doInBackground(String... params) {
    boolean result = false;
    try {
        sockaddr = new InetSocketAddress( host, port );
        socket = new Socket();                                Log.i( "Status : ", "Openning socket");
        socket.connect( sockaddr, timeout );
        publishProgress( "Start Connection... " );            Log.i( "Start Connection... ", "" );
        socket.setOOBInline( true );                          Log.i( "Tcp receiver ", "" );
        if (socket.isConnected()) {
            publishProgress( "CONNECTED" );                   Log.i( "Status : ", "Connected to Server " + host + ":" + port );
            is = socket.getInputStream();                     Log.i( "Get data : ", "Receiving response from Server..." );
            os = socket.getOutputStream();                    Log.i( "Send data : ", "Send data to Server..." );
            for (String p : params) {
                os.write( p.getBytes() );
            }
            os.flush();
            byte[] buff = new byte[2048];
            int buffData = is.read( buff, 0, 2048 );

            while (buffData != -1) {
                String response = new String( buff );
                // Envia os dados para Main
                publishProgress( response );                Log.i( "Get data : ", "Buffer from response..." );
                buffData = is.read( buff, 0, 2048 );
            }
        }else{
            publishProgress("CONNECT ERROR - Disconected ");
        }
    } catch(ConnectException e1){
        publishProgress( "ERROR CONNECTION" );         Log.e( "SocketAndroid :", "Network is unreachable - End for timeout.", e1 );
        result = true;
    } catch (IOException e2) {
        publishProgress( "ERROR CONNECTION" );         Log.e( "SocketAndroid :", "input and output error", e2 );
        result = true;
    } catch (Exception e3) {
        publishProgress( "ERROR CONNECTION" );         Log.e( "SocketAndroid", "Generic error", e3 );
        result = true;
    } finally {
        try {
            if (is != null) {
                is.close();                             Log.i( "ImputStream : ", "close" );
            }
            if (os != null) {
                os.close();                             Log.i( "OutputStream : ", "close" );
            }
            if (socket != null) {
                socket.close();                         Log.i( "Socket : ", "close" );
                publishProgress( "DISCONNECTED" );      Log.i( "Socket : ", "DISCONNECTED" );
            }
        } catch (Exception e) {                         Log.e( "SocketAndroid", "Error closing connection - ", e );
            result = true;
        }
    }
    return result;
}

Mainactivity

  private void startSocket() {
    if (servidor1.isEmpty() && servidor2.isEmpty()) {
        Snackbar.make( btnPanico, "Verifique as configurações do seu app.", Snackbar.LENGTH_LONG ).setAction( "Action", null ).show();
        return;
    }
    if (count <= (atemptcount / 2) && !servidor1.isEmpty()) {
        server = servidor1;
    } else if (count >= (atemptcount / 2) && !servidor2.isEmpty()) {
        server = servidor2;
    }
    // try {
    String txtenviando = getResources().getString( R.string.enviando );
    txtSucess.setText( txtenviando );
    // Recupera host e porta
    String hostPort = String.valueOf( server ).trim();
    int idxHost = hostPort.indexOf( ":" );
    final String host = hostPort.substring( 0, idxHost );
    final int port = Integer.parseInt( (hostPort.substring( idxHost + 1 )) );
    // Instancia a classe de conexão com socket
    st = new SocketTask( host, port, 5000 ) {
        @SuppressLint("SetTextI18n")
        @Override
        protected void onProgressUpdate(final String... progress) {
            SimpleDateFormat sdf = new SimpleDateFormat( "dd/MM/yyyy HH:mm:ss" );
            // Recupera o retorno
            txtStatus.setText( sdf.format( new Date() ) + " - " + progress[0] );
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            exibirProgressbar( true );
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute( aBoolean );
            exibirProgressbar( false );
            Log.i( "onPostExecute : ", "passou" );
        }
    };
    String dados = ("#" + conta + "," + phoneNumber + "," + latitude + "," + longitude + "," + evento + "," + status + "," + DataTime + "$");
    st.execute( dados );

    }

An attempt was this way :

            int len=1;
            byte[] receivedBytes = new byte[len]; // len é o tamanho da resposta esperada
            int total = 0;
            while (total < len)
            {
                byte[] objectAsByte = new byte[socket.getReceiveBufferSize()];
                int pctsize = is.read(objectAsByte);
                System.arraycopy(objectAsByte, 0, receivedBytes, total, pctsize);
                total += pctsize;
            }
            if(receivedBytes.length != -1){
                String response = new String(receivedBytes);
                publishProgress( response );
            }
  • 2

    "when you enter buffData = is.read( Buff, 0, 2048 ); it pauses the thread" - the method read() is blocking, if it has not read all the amount of bytes requested it pauses the thread to wait I/O. You have to do a check of how much data it should read or maybe set a stop character.

  • Could you give me an example? I don’t know where to implect or how to control.

  • Well, let’s search on the internet read() and how it behaves...

  • It’s hard to understand, does anyone have an example ? I hope to get a "@" character back; I actually get it. The method should already be satisfied with this and go to closure in Finish; but it will not.

  • I tried this but gave endless loop while (buffData != -1) { String Response = new String( Buff ); // Send data to Main publishProgress( Response ); if(!Sponse.contains( "@" )) { buffData = is.read( Buff, 0, 2048 ); } }

1 answer

1


You can use getReceiveBufferSize() to know how many bytes you have available in the socket buffer before reading.

byte[] receivedBytes = new byte[len]; // len é o tamanho da resposta esperada
int total = 0;
while (total < len)
{
    byte[] objectAsByte = new byte[socket.getReceiveBufferSize()];
    int pctsize = is.read(objectAsByte);
    System.arraycopy(objectAsByte, 0, receivedBytes, total, pctsize);
    total += pctsize;
}

Thus avoiding having him read more bytes than actually exists, and locking the thread forever. If you need a quick response, you can implement a timeout to get out of while if the data doesn’t arrive in time.

  • Solved. Maybe because it is only a return "@" character, is.read should expect a larger string, no ?

  • And by the way. Because whenever I ask a question I get -1 ? But what’s wrong with my question ? He had given up that forum a while back, because they always do this to me. And I have no one to talk to about it. You know how much it sucks to be here trying to get help and get this kind of thing. Boring.

  • Thank you very much Christian Beregula for the help. Thank you very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.