@ Sergey Pestov , in a nutshell, the process usually proceeds a little differently than you imagine.
The server has a static IP (for example, 8.8.8.8) and it listens to the port (for example, 8888). You have a dynamic IP (say, 10.1.2.100 now), but your router has a static one (say 178.10.20.30) in the external network and 10.1.2.1 in the internal (on another network interface (you are physically connected to it)).
When your client says connect (), the socket receives the address (host: port) from the OS, for example 10.1.2.100:1234. Your OS writes it to the interface that is associated with the router (with the MAC address of the router ). The router forwards the request packet to the address 8.8.8.8:8888, but changes the sender address to 178.10.20.30:10234 (it changes the port number (takes the “free” at the moment)) and remembers that the address 10.1.2.100:1234 on the internal interface corresponds to 178.10.20.30:10234 on the outside.
Thus, the server 8.8.8.8:8888 will receive packets from 178.10.20.30:10234 and send its answers to this address. The router, having received the packet, finds the address of the recipient (you) in its NAT (Network Address Translation) table and forwards the packet to you, but already at the address (changes in the packet header) 10.1.2.100:1234.
In general, it should be clear.