Connect a socket to another PC in same NAT

Hey I've got two machines on the same network. They get their IP info back from an external webserver. Same IP due to NAT but different ports locally. Hmm that's weird.. they can't socket up or even see each other. Example:

Microsoft Telnet> open 1.129.108.250 16054
Connecting To 1.129.108.250...Could not open connection to the host, on port 16054: Connect failed

C:\Users\Andrew>ping 1.129.108.250

Pinging 1.129.108.250 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
    
Ping statistics for 1.129.108.250:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss)

Idk. Is there like an 'external port' to worry about, because of NAT? I mean I start a listener on port 10000, will it still be 10000 to someone else? Even the case, why can't they ping? They're both in my bedroom on same network. Thanks

EDIT:

To explain it better, both machines get their external IP address from my web server, and it's 1.129.108.250 on each. So the port will differentiate. But they seem to not think of each other as being on the same network except by virtue of running on my wifi. It's hotspotted from mobile as if it makes any difference. Also, what would happen if they choose the same port to listen? Will NAT crash or malfunction?

EDIT 2:

How many combinations are there in practice?

PC1 in NAT      PC2 in NAT  (same network)
PC1 in NAT      PC2 in NAT  (different networks)
PC1 not in NAT  PC2 in NAT  (different networks)

Is it true to say that anyone outside the network doesn't need special logic? Since the routers take care to make everything look normal. I guess this is one thing user1686 meant.

If 1.2.3.4:1000 actually maps to 192.168.0.1:10000 then it must behave just like a real endpoint..


Solution 1:

They get their IP info back from an external webserver. Same IP due to NAT but different ports locally.

The port reported by the webserver doesn't mean much. Each new TCP connection gets a completely new local port assigned by the client – even from a single machine without any NAT, the web server would keep seeing different ports every time you hit F5. (Some NATs preserve the ports, others always translate them.)

Hmm that's weird.. they can't socket up or even see each other. Example:

This is not a "listening" port – it isn't accepting new connections; it was only allocated as the source port for a specific outbound connection, and you cannot telnet into it (even if NAT weren't a concern).

Even the case, why can't they ping?

The address reported by the webserver doesn't belong to any of your machines. When behind NAT, the "external" IP address belongs only to the router that's performing NAT (typically yours, but in case of CGNAT it's one at the ISP). So when you're pinging your external IP address, you're always pinging just the router – not any machine behind it.

Most "home" routers are configured to ignore all ping requests to their external address.

Also, what would happen if they choose the same port to listen? Will NAT crash or malfunction?

No, the NAT will just rewrite the ports to not conflict. (All "1:many" NATs have to keep track of every connection in order to un-NAT the inbound responses; the same state table tells them whether there's another connection using this local port.)

Some NATs just always rewrite the source port for every connection, even if there's no conflict.

It's hotspotted from mobile as if it makes any difference

It does. It's very possible that the phone applies "client isolation" for its hotspots and tethering – if that's the case, two devices connected to the same hotspot won't be able to contact each other even using their "private" IP addresses, despite everything seeming like they should be able to. (My Android phone doesn't seem to isolate Wi-Fi hotspot clients, but it does put a wall between Wi-Fi and USB tethering.)

How many combinations are there in practice?

Many. A host could be behind a local NAT, or behind two local NATs (or three!), or behind ISP-managed CGNAT, or behind two local NATs and CGNAT. (Or no NAT at all, of course.)

Each of those NAT layers could be "cone NAT" or "symmetric" – weird names aside, one allocates a mapping usable by all remote endpoints, the other does not. (In a peer-to-peer situation, automated hole-punching is possible in many cases, but not when both peers are behind symmetric-type NATs.)

See the article by Tailscale on how NAT traversal works to see just a few possibilities.

Is it true to say that anyone outside the network doesn't need special logic?

Only if your connections are strictly from inside to outside (e.g. browser making a HTTP connection to a public web server).

My app can listen on 1.2.3.4:10000 but if the NAT changes it to 33.62.123.0:12345, how can i know what the real endpoint is? I can get the IP by asking my website. But how to find out what port I'm actually listening on?

You aren't. There isn't any external port that you're assigned. Outbound connections get temporary NAT mappings assigned whenever the NATing router sees packets go through (and it only lasts as long as that connection); for listening sockets, there won't be any mapping unless someone adds one manually.

If you're lucky, the nearest NAT might be accepting either NAT-PMP (now PCP) or UPnP IGD requests to establish a persistent mapping that allows inbound connections; this is common in e.g. BitTorrent clients. You tell the router your listener's local address:port, and the router's response will have the external address and port that was assigned.

If not... well, you get into the "NAT traversal" territory.

NAT seems to be a huge pain in the ass. And I could go on for days about how TCP was poorly designed.

'Fortunately', NAT isn't actually part of TCP. It's a "short-term bandaid" that got bodged on top of TCP/IP two decades ago and we've been living with it since.