Задать вопрос

Android socket — проблема при отправке данных. Почему данные шлются только после закрытия исходящего потока сокета?

Добрый день!


Пишу клиентское приложение под андроид. Отправление запросов на сервер и получение ответов с сервера. Соединение с сервером через сокеты.


Столкнулся с такой проблемой: данные отсылаются только после закрытия выходящего потока сокета. Опишу ситуацию: есть Asynctask, в котором должно быть открыто ТОЛЬКО ОДНО соединение с сервером. Но у меня не получается это реализовать. Получается сделать только по такой схеме: открыл соединение, отправил данные, принял данные, закрыл соединение. Потому что без закрытия соединения не отсылаются данные на сервер.


Привожу класс AsyncTask:

class InternetRequestAsyncTask extends AsyncTask<String, Integer, String>
    {
        private Socket socket = null;
        private DataOutputStream outStream = null;
        private BufferedReader in;
        private String ip, port;
        final String GPS_MESSAGE = "GPS_MESSAGE";
        final String LOGIN_REQUEST = "LOGIN_REQUEST";
        final String LIST_REQUEST = "LIST_REQUEST";
        private String command = "";

        public InternetRequestAsyncTask(String IP, String PORT) 
        {
            ip = IP;
            port = PORT;
        }

        private void setCommandType(String commandType)
        {
            command = commandType;
        }

        private void connect()
        {
            try {
                socket = new Socket(ip, Integer.parseInt(port));
                socket.setKeepAlive(true);

                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                outStream = new DataOutputStream(socket.getOutputStream());

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

            Log.d("MyTag", "Connected");
        }

        private void disconnect()
        {
            if (socket != null)
            {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (outStream != null)
            {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            Log.d("MyTag", "Disconnected");
        }

        private void writeMessage(String message) throws IOException
        {            
            outStream.writeBytes(message + "\r\n");
        }

        @Override
        protected String doInBackground(String... params) 
        {        
            this.connect();
            
            while (true)
            {
                if (command.equals(GPS_MESSAGE))
                {
                                        
                    try {
                        this.writeMessage(GPS_MESSAGE);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                    command = "";
                    
                } else
                {
                    if (command.equals(LOGIN_REQUEST))
                    {
                                                
                        try {
                            this.writeMessage(LOGIN_REQUEST);
                            
                            StringBuilder sb = new StringBuilder();
                            String str;
                            
                            while ((str = in.readLine()) != null)
                            {
                                sb.append(str);
                            }
                            Log.d("MyTag", sb.toString());

                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        
                        command = "";
                        
                    } else
                    {
                        if (command.equals(LIST_REQUEST))
                        {
                                                    
                            try {
                                this.writeMessage(LIST_REQUEST);
                                
                                StringBuilder sb = new StringBuilder();
                                String str;
                                
                                while ((str = in.readLine()) != null)
                                {
                                    sb.append(str);
                                }
                                Log.d("MyTag", sb.toString());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            
                            command = "";
                            
                        } else
                        {
                            if (command.equals("EXIT"))
                            {
                                break;
                            }
                        }
                    }
                }
            }

            return null;
        }

        @Override
        protected void onPostExecute(String result) 
        {
            this.disconnect();

            super.onPostExecute(result);
        }

        @Override
        protected void onCancelled() 
        {
            this.disconnect();

            super.onCancelled();
        }
    }



использую так:
InternetRequestAsyncTask irat = new InternetRequestAsyncTask(IP, PORT);
irat.execute();



и по нажатию на кнопки передаю нужные команды:
irat.setCommandType(commandType);


в таком виде код (когда connect() вызывается только один раз, а disconnect() по окончанию работы потока) сообщение на сервер шлется только один раз.


Помогите разобраться. Нужно открыть ОДНО соединение в AsyncTask и многоразово использовать его для отправки/приема сообщений.
  • Вопрос задан
  • 9497 просмотров
Подписаться 5 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
Попробуйте использовать метод flush() в тот момент, когда хотите "протолкнуть" данные из буфера потока в сеть.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы