Java-сокеты и удаленные соединения

Какие'самый подходящий способ определить, был ли сокет удален или нет? Или пакет действительно был отправлен?

У меня есть библиотека для отправки Apple Push-уведомлений на iPhone через шлюзы Apple (доступно на GitHub). Клиенты должны открыть сокет и отправить двоичное представление каждого сообщения; но, к сожалению, Apple нене вернуть никакого подтверждения вообще. Соединение также можно использовать для отправки нескольких сообщений. Я'м с использованием простых соединений Java Socket. Соответствующий код:

Socket socket = socket();   // returns an reused open socket, or a new one
socket.getOutputStream().write(m.marshall());
socket.getOutputStream().flush();
logger.debug("Message \"{}\" sent", m);

В некоторых случаях, если соединение прерывается во время отправки сообщения или прямо перед ним;Socket.getOutputStream().write() успешно заканчивается, хотя. Я ожидаю этогоиз-за окна TCP неТ исчерпан.

Есть ли способ, которым я могу точно сказать, действительно ли пакет попал в сеть или нет? Я экспериментировал со следующими двумя решениями:

Вставьте дополнительныйsocket.getInputStream().read() работа с тайм-аутом 250 мс. Это вызывает операцию чтения, которая завершается неудачно при разрыве соединения, но в противном случае зависает на 250 мс.

установить размер буфера отправки TCP (например,Socket.setSendBufferSize()) к сообщению двоичный размер.

Оба метода работают, но они значительно ухудшают качество обслуживания; Пропускная способность составляет не более 100 сообщений в секунду и не более 10 сообщений в секунду.

Какие-либо предложения?

ОБНОВИТЬ:

Оспаривается множественные ответы, ставящие под сомнение возможность описанного. Я построилединица измерения" тесты поведения ям описания. Проверьте случаи блока вСуть 273786.

Оба модульных теста имеют два потока: сервер и клиент. Сервер закрывается, пока клиент отправляет данные без IOException в любом случае. Вот основной метод:

public static void main(String[] args) throws Throwable {
    final int PORT = 8005;
    final int FIRST_BUF_SIZE = 5;

    final Throwable[] errors = new Throwable[1];
    final Semaphore serverClosing = new Semaphore(0);
    final Semaphore messageFlushed = new Semaphore(0);

    class ServerThread extends Thread {
        public void run() {
            try {
                ServerSocket ssocket = new ServerSocket(PORT);
                Socket socket = ssocket.accept();
                InputStream s = socket.getInputStream();
                s.read(new byte[FIRST_BUF_SIZE]);

                messageFlushed.acquire();

                socket.close();
                ssocket.close();
                System.out.println("Closed socket");

                serverClosing.release();
            } catch (Throwable e) {
                errors[0] = e;
            }
        }
    }

    class ClientThread extends Thread {
        public void run() {
            try {
                Socket socket = new Socket("localhost", PORT);
                OutputStream st = socket.getOutputStream();
                st.write(new byte[FIRST_BUF_SIZE]);
                st.flush();

                messageFlushed.release();
                serverClosing.acquire(1);

                System.out.println("writing new packets");

                // sending more packets while server already
                // closed connection
                st.write(32);
                st.flush();
                st.close();

                System.out.println("Sent");
            } catch (Throwable e) {
                errors[0] = e;
            }
        }
    }

    Thread thread1 = new ServerThread();
    Thread thread2 = new ClientThread();

    thread1.start();
    thread2.start();

    thread1.join();
    thread2.join();

    if (errors[0] != null)
        throw errors[0];
    System.out.println("Run without any errors");
}

[Между прочим, у меня также есть библиотека тестирования параллелизма, которая делает настройку немного лучше и понятнее. Оформить заказ образца также.

При запуске я получаю следующий вывод:

Closed socket
writing new packets
Finished writing
Run without any errors

Ответы на вопрос(3)

Ваш ответ на вопрос