2015-11-09 3 views
1

Пожалуйста, помогите мне понять розетки. Я отправляю данные акселерометра с Android через сокеты на ПК, и через некоторое время прием данных прекращается, а через некоторое время я получаю «закрытое соединение клиента». Это связано с нарушением сети и просто сокеты не слишком надежны?Сокет закрывается при отправке большого количества данных?

public class Connection { 

    private String IP; 
    private int port; 
    private Socket socket; 
    private PrintWriter output; 

    public void connect(String IP, int port) { 
     this.IP = IP; 
     this.port = port; 
     new Connect().execute(); 
    } 

    public void sendText(String data) { 
     new SendText().execute(data); 
    } 

    public void disconnect() { 
     new Disconnect().execute(); 
    } 

    public boolean isConnected() { 
     if (socket != null) 
      return socket.isConnected(); 
     else return false; 
    } 

    private class Connect extends AsyncTask<Void, Void, Void> { 

     @Override 
     protected Void doInBackground(Void... params) { 
      try { 
       socket = new Socket(IP, port); 
       OutputStream out = socket.getOutputStream(); 
       output = new PrintWriter(out); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
    } 

    private class SendText extends AsyncTask<String, Void, Void> { 

     @Override 
     protected Void doInBackground(String... params) { 
      output.println(params[0]); 
      output.flush(); 
      return null; 
     } 
    } 

    private class Disconnect extends AsyncTask<Void, Void, Void> { 

     @Override 
     protected Void doInBackground(Void... params) { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
    } 

} 

Часть класса акселерометр:

public void onSensorChanged(SensorEvent event) { 
     Sensor mySensor = event.sensor; 

     if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
      float x = event.values[0]; 
      float y = event.values[1]; 
      float z = event.values[2]; 
      connection.sendText("x"+Float.toString(x)+"a"); 
      connection.sendText("y"+Float.toString(y)+"s"); 
      connection.sendText("z"+Float.toString(z)+"d"); 
     } 
    } 

Должен ли я просто обнаружить, отправив некоторые «пинг» и «понг» текст, чтобы знать, когда соединение разрывается, а затем просто восстановить?

Или, может быть, лучше просто использовать некоторые библиотеки, как это: https://github.com/EsotericSoftware/kryonet

приложение будет использоваться для дистанционного управления небольшого транспортного средства.

+1

Думаете, вы могли бы воспользоваться некоторыми практиками безопасности потоков? Вы вызываете 'sendText' три раза подряд, каждый из которых создает новый поток/задачу, используя выходной поток. Не уверен, что это может вызвать некоторые проблемы. возможно, выполните синхронизацию (вывод) {...} ' – binnyb

ответ

0

Вы используете несколько асинтасккеров с одним разъемом, и это вызывает проблемы, которые вы описали.

Вы должны реализовать один сокет для каждого асинтезатора. Избавьтесь от asyncclasses Connection и Disconnection и просто выполните «Connect» -> «SendText» -> «Отключить» вообще внутри doInBackground в одном классе asynctask.

Или вы должны реализовать очередь и поместить всю информацию в строку и реализовать службу для обработки этой строки, отправив текст с помощью одного сокета, например «Подключить» -> «Записи строки процесса» -> «Отключить».

+0

. Должен ли я иметь статическую строку в моей службе и проверять бесконечный цикл в этой службе, заполняется ли эта строка или нет, а затем отправлять данные в зависимости от этого? – Defozo

+0

Это не лучший способ сделать очередь ... Я предпочитаю использовать Collections.synchronizedList() ... и в то время как сенсорные события заполняются, сервис заполняет иены ... получил? – Christian

Смежные вопросы