Ответ 1
В TCP есть TCP Window, который используется для управления потоком. TCP позволяет только определенное количество данных оставаться неподтвержденным одновременно. Если сервер производит данные быстрее, чем клиент потребляет данные, тогда количество данных, которые не подтверждены, увеличится до тех пор, пока окно TCP не будет "полным", в этот момент отправляющий стек TCP будет ждать и больше не будет отправлять данные до тех пор, пока клиент подтверждает некоторые данные, которые ожидаются.
В UDP нет такой системы управления потоком; это ненадежно в конце концов. UDP-стеки как на клиенте, так и на сервере разрешают отбрасывать дейтаграммы, если они чувствуют себя так, как и все маршрутизаторы между ними. Если вы отправляете больше датаграмм, чем ссылка может доставить клиенту, или если ссылка поставляет больше датаграмм, чем может получить ваш код клиента, некоторые из них будут выброшены. Сервер и клиентский код, вероятно, никогда не узнают, если вы не создали какой-либо надежный протокол по базовому UDP. Хотя на самом деле вы можете обнаружить, что датаграммы НЕ выбрасываются сетевым стеком и что драйверы NIC просто пережевывают весь доступный неуправляемый пул и в конечном итоге приводят к сбою системы (см. этот блог для более подробной информации).
Назад с TCP, как ваш код сервера работает с окном TCP Window, будет зависеть от того, используете ли вы блокирующий ввод-вывод, неблокирующий ввод-вывод или асинхронный ввод-вывод.
-
Если вы используете блокирующий ввод-вывод, ваши вызовы отправки блокируются и ваш сервер будет замедляться; эффективно ваш сервер теперь находится в шаге блокировки с вашим клиентом. Он не может отправлять больше данных, пока клиент не получит ожидающие данные.
-
Если сервер использует неблокирующий ввод-вывод, вы, скорее всего, получите сообщение об ошибке, сообщающее, что вызов заблокирован; вы можете делать другие вещи, но ваш сервер должен будет повторно отправить данные позже...
-
Если вы используете асинхронный ввод-вывод, все может быть сложнее. С асинхронным вводом-выводом с использованием портов ввода-вывода ввода-вывода в Windows, например, вы не заметите ничего другого. Ваши совпадающие посылы по-прежнему будут приниматься просто отлично, но вы можете заметить, что они занимают больше времени. Наложенные посылки помещаются в очередь на вашем сервере и используют память для ваших перекрывающихся буферов и, вероятно, используют "не выгружаемый пул". Если вы продолжаете выдавать перекрывающиеся отправки, тогда вы рискуете исчерпать память не выгружаемого пула или использовать потенциально неограниченный объем памяти в качестве буферов ввода-вывода. Поэтому при асинхронном вводе-выводе и серверах, которые МОГУТ генерировать данные быстрее, чем их клиенты могут их потреблять, вы должны написать свой собственный код управления потоком, который вы используете, используя пополнение от ваших записей. Я написал об этой проблеме в своем блоге здесь и здесь и моя серверная платформа предоставляет код, который автоматически обрабатывает его.
Что касается данных "в полете", то стеки TCP в обоих одноранговых узлах будут обеспечивать, чтобы данные поступали как ожидалось (то есть по порядку и без чего-либо отсутствующего), они будут делать это путем повторной отправки данных по мере необходимости.