Нет причин для того, чтобы это создавало проблемы, при условии, что одна сторона не находится за NAT, а сторона, которая находится за NAT, отправляет первый пакет. Просто следуйте этим правилам:
1) На сервере проверьте список всех IP-адресов, которые имеет хост. Свяжите гнездо UDP с каждый IP-адрес. Вы можете пропустить это, если на сервере только один общедоступный IP-адрес, и это единственный адрес, на который он будет установлен.
2) Отправьте ответ UDP на тот же сокет, на который вы получили запрос. Это важно для обеспечения того, чтобы адрес источника ответа соответствовал целевому адресу.
3) Отправьте UDP-ответ точно на тот же IP-адрес и порт, на который вы получили запрос. Игнорируйте все, что говорит другой конец, о том, что он думает о своем IP-адресе, или о том, какой порт он считает отправкой.
И несколько замечаний:
Под «сервером», я имею в виду ту сторону, которая еще не за NAT. Если у вас нет различия между клиентом и сервером, следуйте правилам сервера для обеих сторон, и все будет в порядке.
Эти правила применяются независимо от того, является ли пакет, строго говоря, ответом. Они применяются к любому пакету, который вы ожидаете получить на другой стороне.
Помните, что вы не можете полагаться на информацию IP/port в пакете, чтобы сообщить вам, откуда пришел пакет, поскольку NAT может его изменить. Поэтому вам нужно будет разместить достаточную информацию в полезной нагрузке дейтаграммы для этого. В идеале ожидайте, что IP-порт конечной точки может измениться в любое время и отправить все пакеты на IP/порт, с которого вы последний раз получали пакет от этого конкретного клиента.
Он должен работать нормально. Ошибка 10049 означает, что вы используете неправильный адрес. Если проблема в том, что вы получаете код ошибки, это связано с ошибкой в коде, которую вам нужно найти и исправить. Какая операция получает эту ошибку? Какие параметры вы передаете в этой операции? –
здесь вы можете увидеть код сервера: SN = новый Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint IEP = новый IPEndPoint (IP, порт); SN.SetIPProtectionLevel (IPProtectionLevel.Unrestricted); SN.Bind (IEP); IPEndPoint IPS = новый IPEndPoint (IPAddress.Parse («[мой ip]»), 2000); EndPoint EP = (EndPoint) IPS; SN.BeginReceiveFrom (BR, 0, BR.Length, SocketFlags.None, ref EP, новый AsyncCallback (OnReceive), EP); –
Это не может работать на сервере! Вы не можете узнать IP/порт, пока не получите UDP-пакет, и вы не сможете получить пакет UDP до тех пор, пока у вас не будет установлен сокет! Вам необходимо связать задолго до того, как вы получите первый пакет UDP, задолго до того, как вы узнаете IP-адрес и порт другого конца. –