Если вы используете многоадресную или широковещательную связь UDP, то часто имеет смысл привязать несколько программ к одному и тому же порту UDP, и это можно сделать, если вы вызовете setsockopt()
с соответствующими аргументами перед вызовом bind()
на нем:
const int trueValue = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &trueValue, sizeof(trueValue));
#ifdef __APPLE__
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &trueValue, sizeof(trueValue));
#endif
В этом сценарии копия каждого UDP-пакета многоадресной / широковещательной рассылки, полученного через порт, будет доставлена на каждый из сокетов, привязанных к этому порту (что примерно соответствует поведениюполучить, если каждая программа работала на отдельном компьютере, и, следовательно, обычно то, что вам нужно)
OTOH, если вы отправляете только одноадресные UDP-пакеты (то есть пакеты, предназначенные для передачи одному получателю), то обычно этобесполезно связывать несколько программ с одним и тем же портом, поскольку каждый отправленный вами UDP-пакет будет приниматься ровно одной принимающей программой, а с несколькими программами, прослушивающими один и тот же порт, неизвестно / непредсказуемо, какая это будет программа.Например, в вашем случае ваша клиентская программа может отправить пакет, а сервер не получит его, потому что пакет был помещен в очередь в буфере сокета клиента.Так что в этом случае лучше связать клиент и сервер с разными портами.(Имейте в виду, что любая программа, которая получает пакет UDP, может легко узнать, к какому порту подключен отправитель пакета, вызвав recvfrom()
для получения пакета и посмотрев содержимое аргумента address
впоследствии; поэтому она должнасервер будет просто отвечать на пакеты, отправленные ему клиентом, даже если клиент использует абсолютно произвольный / произвольный порт UDP при каждом запуске. Если вы сообщаете своему клиенту bind()
для порта 0, сетевой стек будетвыберите доступный в настоящее время UDP-порт для привязки к нему)