2016-12-30 4 views
0

В Java можно записать пару байтов (или сколько бы байтов, размер которых меньше размера буфера) в выходной поток сокета, а затем очистить его, в случае необходимости некоторых байтов для отправки немедленно. В Win32 API, похоже, нет какой-либо функции флеша, поэтому я чувствую, что «промывка» в этом случае просто заполняет остальную часть буфера фиктивными байтами (возможно, нулями), чтобы заставить функцию отправки, , отправьте данные. Мой вопрос: как Java (или даже C#, возможно) реализует такую ​​вещь под капотом? То есть, если бы у меня был Java-сокет, связанный с гнездом Win32 где-нибудь, как бы они общались, учитывая, что потребуется некоторая промывка? Например, если буфер буфера Java был сброшен (вызывая flush на сокете OutputStream), что бы я получил на стороне Win32 (позвонив по номеру recv)? И наоборот? Будет ли я видеть какое-то поведение дополнений? Может ли сторона Win32 знать размер буфера на стороне Java? Что-то несвязанное?Win32 API против стирания сокетов Java (TCP)

+0

Вы пытались изучить источники? .Net полностью доступен на github, и вы можете увидеть, как именно он реализован –

ответ

1

Сначала напомним, что TCP обеспечивает двунаправленный поток байтов. С одной стороны вы пишете байты в сокет, а другая сторона может читать их из сокета. Нет никакой гарантии, приведет ли запись 4 байта к одному считываемому вызову, который извлекает 4 байта на другом конце. Он также может быть 2 раза 2 байта. Это не пакеты или буферы, и поэтому «заполнение остальной части буфера фиктивными байтами» кажется плохой идеей, так как другая сторона в конечном итоге получит эти фиктивные байты (и интерпретирует их для чего угодно).

Далее на вопрос:
На базе всего приложения есть API-интерфейсы сокетов ОС, которые обеспечивают вызовы записи/отправки для сокета. Когда вы пишете в гнездо ОС, байты, которые записываются, в основном записываются только в буфер отправки сокета ОС, из которого они будут отправляться на удаленную сторону в какой-то момент времени. Этот момент времени зависит от того, как заполняется состояние буфера отправки и как выглядят вещи в сети (окна TCP, перегрузка сети и т. Д.). Однако вам, как правило, не нужно заботиться об этом, ОС просто отправит данные в конце концов, и нет необходимости что-то скрывать. В ОС есть одна настройка, которая может использоваться для влияния на поведение отправки, которое является алгоритмом nagle (или TCP_NODELAY). Если алгоритм nagle отключен (NODELAY = true), это означает, что ОС будет пытаться немедленно отправить данные после вызова записи и не ждет больше данных из приложения, чтобы отправлять меньше IP-пакетов. Вы можете использовать , чтобы уменьшить латентность в случае небольших пакетов, но в этом нет необходимости, так как ОС будет отправлять данные в любом случае. Так что это не флеш в смысле необходимого флеша.

Для стороны Java я не совсем уверен, что делает флеш. Возможно, что Java OutputStream имеет внутренний буфер, который записывается только в сокет ОС с системным вызовом записи, как только достигается определенное количество байтов в буфере или вызывается флеш. Или флеш существует исключительно для того, чтобы удовлетворить базовый класс OutputStream и ничего лишнего. Вы должны быть в безопасности, используя флеш на стороне Java (или на других платформах, где он существует) и ничего особенного не делает в собственных API-интерфейсах сокетов.

2

Промывка выходного потока сокета Java не делает ничего. Промывка BufferedOutputStream что-то делает, но только для буфера на стороне приложения. В любом случае нет системного вызова, кроме send() или write(), подразумеваемого флешем. Вы ищете нечто, чего не существует.

, так что я чувствую, что «топить» в данном случае просто дополняя остальную часть буфера с фиктивными байтов (вероятно, обнуляет) ...

No.

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

  • Нет связанных вопросов^_^