Заставляем соединение с сокетом ждать ответа после отправки команды

#java #android #sockets

#java #Android #сокеты

Вопрос:

Из приложения Android я создаю соединение с сокетами с помощью служб Android. Идея в том, что я подключаюсь к серверу при запуске действия и оставляю соединение с сокетом открытым для доступа к другим частям приложения.

Теперь то, что я пытаюсь сделать, это то, что я пишу команду на сервер, используя буферизованный writer. После записи я хочу реализовать проверку, получен ли уже ответ или нет. Я пытаюсь сделать это с помощью while (inStream.available() == 0) цикла. Однако это не работает. Есть идеи, как заставить приложение ждать ответа конкретной команды до обработки дальнейшего кода?

Подключение к сокету:

     public class connectSocket implements Runnable
{
    @Override
    public void run()
    {
        try
        {
            Log.v("DEV","SocketClass, connectSocket");
            SocketAddress socketAddress = new InetSocketAddress(SERVERIP,SERVERPORT);
            command = "authorization";

            try
            {
                socket = new Socket();
                socket.setTcpNoDelay(true);
                socket.setSoTimeout(5000);
                socket.connect(socketAddress, 5000);

                if (socket.isConnected())
                {
                    Log.v("DEV","SocketClass successfully connected!");

                    out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    inStream = new DataInputStream(socket.getInputStream());

                    int bytesRead;
                    int count = 1;

                    while ((bytesRead = in.read()) > 0 amp;amp; count != 3)
                    {
                        if (count == 1)
                        {
                            out.write(command   "rn");
                            out.flush();
                        }

                        while (inStream.available() == 0)
                        {
                            Log.v("DEV", "sleep " inStream.available());
                            android.os.SystemClock.sleep(100);
                        }

                        StringTokenizer filterToken = new StringTokenizer(in.readLine(), "^");
                        String temp = filterToken.nextToken();

                        Log.v("DEV", "SocketClass Tokenizer: " temp);

                        if (temp.equals("cmd_main"))
                        {
                            response = filterToken.nextToken();

                            Intent ret = new Intent();
                            ret.setAction(Testas.RECEIVE_AUTHORIZATION);
                            ret.putExtra("response",response);
                            sendBroadcast(ret);
                            count = 2;
                        }

                        count  ;
                    }
                }
            }

            catch (Exception e)
            {
                Log.e("TCP",e.toString());
            }
        }

        catch (Exception e)
        {
            Log.e("DEV",e.toString());
        }
    }
}
  

Здесь я хочу дождаться ответа:

     class trackerStatus implements Runnable
{
    @Override
    public void run()
    {
        Log.v("DEV", "Socket Class, trackerStatus");

        try
        {
            int bytesRead;
            boolean parse = true;
            command = "command";
            int count = 1;

            while ((bytesRead = in.read()) > 0 amp;amp; parse)
            {
                if (count == 1)
                {
                    out.write(command   "rn");
                    out.flush();
                }

                while (inStream.available() == 0)
                {
                    ////this part is not working
                    Log.v("DEV", "sleep " inStream.available());
                    android.os.SystemClock.sleep(100);
                }
                Log.v("DEV", "NoSleep " inStream.available());
                response = in.readLine();

                Log.v("DEV","ReadLine: " response);

                if (response == null || "".equals(response.trim()))
                {
                    Log.v("DEV","Test Empty");

                    Intent ret = new Intent(Testas.RECEIVE_TRACKER_STATUS);
                    ret.putExtra("status", "OFFLINE");
                    LocalBroadcastManager.getInstance(SocketService.this).sendBroadcast(ret);

                    parse = false;
                }

                else
                {
                    StringTokenizer filterToken = new StringTokenizer(response, "^");
                    String temp = filterToken.nextToken();

                    if (temp.equals("trackerinfo"))
                    {
                        StringTokenizer extraFilter = new StringTokenizer(response, "|");
                        temp = extraFilter.nextToken();
                        String[] separate = temp.split(":");

                        if (separate[1].equals(carId))
                        {
                            Intent ret = new Intent();
                            ret.setAction(Testas.RECEIVE_TRACKER_STATUS);
                            ret.putExtra("status", "ONLINE");
                            sendBroadcast(ret);
                            parse = false;
                        }

                    }
                }

                count  ;
            }
        }

        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
  

Комментарии:

1. Прочитайте документацию available(), для реализации совершенно законно всегда возвращать 0, несмотря на наличие доступных данных.

2. Вот почему я спрашиваю здесь. Может быть, кто-нибудь знает, как дождаться, пока данные будут доступны для обработки следующего кода?

3. Указание того, что означает «не работает», значительно помогло бы ответить на вопрос. Какую разницу вы обнаруживаете между тем, что происходит на самом деле, и тем, что вам нужно, чтобы произошло?

4. Неважно, это было давно — для меня это больше не имеет значения, и я не помню, в чем была проблема.

Ответ №1:

             while (inStream.available() == 0)
            {
                ////this part is not working
                Log.v("DEV", "sleep " inStream.available());
                android.os.SystemClock.sleep(100);
            }
            Log.v("DEV", "NoSleep " inStream.available());
  

Удалите все это.

             response = in.readLine();
  

Сохраните это. Оно будет блокироваться до тех пор, пока не будут доступны данные или не будет обнаружен конец потока.