Большинство персональных компьютеров в наши дни расположены за брандмауэрами, которые блокируют любые входящие UDP-пакеты - на самом деле, большинство персональных компьютеров в наши дни также находятся за уровнем трансляции NAT и даже не имеют своего собственного Inte rnet -routable. Айпи адрес. Я бы побеспокоился об этом, прежде чем беспокоиться об отсутствии случайного входящего UDP-сообщения из-за проблем с синхронизацией.
Тем не менее, в случае, если ваш клиент работает с открытым Inte rnet (или за брандмауэром, который настроен на пропуск пакетов UDP), проблема синхронизации на самом деле не является проблемой, поскольку сетевой стек выделяет буфер входящих данных для каждого сокета как часть вызова socket()
. После успешного вызова bind()
для сокета все UDP-пакеты, поступающие на порт этого сокета, будут помещены в буфер входящих данных сокета и готовы к передаче вашему коду при следующем вызове recvfrom()
. Важно отметить, что эта буферизация будет происходить независимо от того, находится ли ваш поток внутри вызова recvfrom()
или нет.
Возможно заполнение входящего буфера данных (он имеет конечный размер, обычно около 64 КБ) ); в этот момент любые дополнительные входящие пакеты UDP будут отброшены. Обычный способ избежать этого - убедиться, что вы вызываете recvfrom()
как можно скорее, или, если этого недостаточно, вы можете использовать setsockopt()
, чтобы указать сетевому стеку увеличить размер входящего буфера данных сокета.
Между тем, ваши вызовы sendto()
, скорее всего, завершатся sh быстро, поскольку sendto()
возвращается, как только данные в вашем массиве копируются в буфер исходящих данных сокета. В частности, sendto()
не ожидает байтов до go по сети или (обычно) даже байтов до вашей сетевой карты. В худшем случае он может блокироваться, пока в буфере исходящих данных не будет достаточно места для размещения данных; и буфер исходящих данных всегда истощается со скоростью линии вашего сетевого устройства.