Фон
Мое приложение собирает данные с телефона и отправляет их на удаленный сервер.
Данные сначала сохраняются в памяти (или в файле, когда он достаточно большой) и каждые X секунд или около тогоприложение сбрасывает эти данные и отправляет их на сервер.
Очень важно, чтобы каждый отдельный фрагмент данных отправлялся успешно, я бы предпочел отправлять данные дважды, а не вообще.
Проблема
В качестве теста я настроил приложение на отправку данных с отметкой времени каждые 5 секунд, это означает, что каждые 5 секунд на сервере появляется новая строка.
Если я убью сервер, я ожидаю, чтоСтроки для остановки, теперь они должны быть записаны в память.
Когда я снова включу сервер, я смогу подтвердить, что никаких событий не пропущено.
Проблема, однако, заключается в том, что когда япри остановке сервера требуется около 20 секунд для начала операций ввода-вывода, что означает, что в течение этих 20 секунд приложение успешно отправляет события и удаляет их из памяти.но они никогда не доходят до сервера и теряются навсегда.
Мне нужен способ убедиться, что данные действительно достигают сервера.
Возможно, это один из более простых вопросов TCP, но нетем не менее, я не нашел никакого решения.
Материал, который я пробовал
Дополнительная информация
Я не могу изменить способсервер отвечает, что означает, что я не могу сказать серверу подтвердить данные (это больше, чем механизм TCP), сервер просто будет молча принимать данные, не отправляя ничего обратно.
Фрагмент кода
Инициализация класса:
socket = new Socket(host, port);
socket.setTcpNoDelay(true);
Куда отправляются данные:
while(!dataList.isEmpty()) {
String data = dataList.removeFirst();
inMemoryCount -= data.length();
try {
OutputStream os = socket.getOutputStream();
os.write(data.getBytes());
os.flush();
}
catch(IOException e) {
inMemoryCount += data.length();
dataList.addFirst(data);
socket = null;
return false;
}
}
return true;
Обновление 1
Я скажу это снова, я не могу изменить поведение сервера.
Он получает данные по TCP иd UPD и не отправляет никаких данных обратно, чтобы подтвердить получение.Это факт, и в идеальном мире сервер подтвердит данные, но этого просто не произойдет.
Обновление 2
Решение, опубликованное Fraggle, работает идеально (закрытиесокет и ожидание закрытия входного потока).
Это, однако, связано с новым набором проблем.
Поскольку я разговариваю по телефону, я должен предположить, что пользователь не может отправить бесконечное количествобайтов, и я хотел бы, если возможно, сократить весь трафик данных.
Меня не беспокоит издержки, связанные с открытием нового сокета, эти несколько байтов не будут иметь значения.Однако меня беспокоит то, что каждый раз, когда я подключаюсь к серверу, мне приходится посылать короткую строку, указывающую, кто я.
Сама строка не такая длинная (около 30 символов), но она складывается, еслиЯ закрываю и открываю сокет слишком часто.
Одно из решений состоит в том, чтобы «сбрасывать» данные каждые X байтов, проблема в том, что я должен выбирать X мудро;если он слишком большой, будет отправлено слишком много повторяющихся данных, если сокет выйдет из строя, а если он слишком мал, слишком большие издержки.
Окончательное обновление
Мое окончательное решение - "очистите сокет, закрыв его каждые X байтов, и если все не выздоровело, эти байты X будут отправлены снова.
Возможно, это создаст несколько дублирующих событий на сервере, но их можно отфильтровать там.