Давайте ещё раз.
На каком порту вы начинаете слушать входящие соединения?
Работать всё, на примере TCP, должно так:
1. Клиент устанавливает соединение с публичным сервером:
192.168.1.100:12345 -> 1.2.3.4:80
Порт 12345 со стороны клиента выделяется, как правило, автоматически операционной системой клиента.
2. NAT выделяет публичную пару Ip-адрес: порт для этого соединения, и запоминает её:
(клиент) 192.168.1.100:12345 -> (NAT)(5.6.7.8:11111) -> (сервер)1.2.3.4:80
Соответственно, с точки зрения сервера, в нему подключились с пары адрес:порт 5.6.7.8:11111
3. Теперь, внимание!
Клиент, ожидая входящие соединения, начинает слушать на порту 12345, поскольку именно для этого порта пробита "дырка" в NAT.
Эта технология так и называется: Hole Punching.
Про другие порты, открытые на этом клиенте, NAT ничего не знает.
4. Кто-то снаружи устанавливает TCP-соединение с парой адрес:порт 5.6.7.8:11111.
NAT знает, что за публичной парой 5.6.7.8:11111 скрывается, на самом деле, "серая" пара 192.168.1.100:12345, подменяет в TCP SYN-пакете destination address и destination port c 5.6.7.8:11111 на 192.168.1.100:12345, и отправляет этот ip-пакет клиенту.
Клиент, получив запрос на соединение на порту 12345, подтверждает установление соединения.
Соответственно, есть три момента, которые стоит проверить:
1. После установления соединения с внешним сервером, клиент должен поднять Listening Socket на том же source TCP port, с которым было установлено соединение с внешним сервером
2. На NAT должна быть включена функциональность Hole Punching
3. Для успешного установления соединения между находящимися за NAT узлами по их публичным адресам, на NAT должна быть включена отвечающая именно за это функциональность Hairpinning.