Search code examples
pythonsocketsnat

Python socket NAT port address


I have a client socket behind a NAT and I want to get the local port number used by the process.

To illustrate my question, here's a quick example.

Let's say I create a server using the following code:

welcome_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
welcome_socket.bind(("", 1500))
welcome_socket.listen(5)

I then listen for incoming connections:

(client_socket, address) = self.welcome_socket.accept()

I connect from a client (behind a NAT) using the following code:

sock = socket.create_connection(("server_address", 1500))

Here is where I'm a little confused.

The address I get on the server side has the public address of the WiFi network the client is connected to (which I expect) and some port number, which based on my understanding of NATs, should be different from the actual port number used by the client and is used for address translation.

However, if I used the getsockname() function on the client, I get the same port number as the one given by the server.

Returning to the example in code.

On the server:

client_socket.getpeername()
>>> ('WiFi_address', 4551)

On the client:

sock.getsockname()
>>> ('local_address', 4551)

So, both port numbers are the same, even though the client is behind a NAT. How is this the case? Am I misunderstanding how the NAT works? Or is there another command to get the physical address that the client socket is bound to?

Any insight would be appreciated.


Solution

  • It is likely that the Router is using Port Address Translation (or one-to-many NAT). The wiki link further quotes

    PAT attempts to preserve the original source port. If this source port is already used, PAT assigns the first available port number starting from the beginning of the appropriate port group 0-511, 512-1023, or 1024-65535. When there are no more ports available and there is more than one external IP address configured, PAT moves to the next IP address to try to allocate the original source port again. This process continues until it runs out of available ports and external IP addresses.

    And that should be the reason why you are seeing port 4551 on the server.

    (This link should also help to clarify the difference between NAT and PAT)