Поток вывода сокета с DataOuputStream - каковы гарантии? - PullRequest
0 голосов
/ 13 августа 2011

Глядя на код:

private static void send(final Socket socket, final String data) throws IOException {
    final OutputStream os = socket.getOutputStream();
    final DataOutputStream dos = new DataOutputStream(os);
    dos.writeUTF(data);
    dos.flush();
}

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

Ответы [ 2 ]

3 голосов
/ 13 августа 2011

Существует большая разница между отправленным и полученным.Вы можете успешно отправлять данные из приложения, но затем оно передает

  • ОС на вашем компьютере
  • сетевой адаптер
  • коммутатору (-ам) насеть
  • сетевой адаптер на удаленном компьютере
  • операционная система на удаленном компьютере
  • буфер приложения на удаленном компьютере
  • независимо от того, что приложение делает сit.

Любой из этих этапов может закончиться неудачей, и ваш отправитель не будет мудрее.

Если вы хотите знать, что приложение получило и обработало данные успешно, оно должно отправитьВы возвращаете сообщение о том, что это произошло.Когда вы получаете это, тогда вы знаете, что оно было получено.

1 голос
/ 13 августа 2011

Да, может случиться несколько вещей.Прежде всего, имейте в виду, write возвращается очень быстро , поэтому не думайте, что выполняется много ошибок (все мои данные подтверждены?).

Дверь № 1

Вы write и flush ваши данные.TCP старается изо всех сил доставить его.Что означает, что он может выполнять ретрансляции и тому подобное.Конечно, ваш send не застревает в течение такого длительного периода времени (в некоторых случаях TCP пытается в течение 5-10 минут, прежде чем обстреливает соединения).Таким образом, вы никогда не узнаете, действительно ли другая сторона получила ваше сообщение.При следующей операции в сокете вы получите сообщение об ошибке.

Дверь № 2

Вы write и flush ваши данные.Из-за непостоянства MTU и из-за того, что строка длинная, она отправляется в нескольких пакетах.Итак, ваш ровесник reads некоторые из них и представляет их пользователю, прежде чем получить все это.

Итак, представьте, что вы отправляете: "Привет тьма, мой старый друг, я пришел поговорить с вами снова«.Другая сторона может получить «Привет тьма м» .Однако, если он выполнит последующие read с, он получит все данные.Таким образом, удаленная сторона TCP фактически получила все, она ACKed все, но пользовательскому приложению не удалось read данные, чтобы вывести его из рук TCPs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...