Ports with python sockets, are they random?
Question: I am trying to learn python sockets, but am becoming very confused by the
results of the example code from the website ([found
here](http://www.tutorialspoint.com/python/python_networking.htm)).

The only modification I have made is replacing `socket.gethostname()` in the
server with the local IP of my server, to allow me to run this on two
computers.

When I connect, attempting to connect on port 12345 as in the example, I get
this output:

`Got connection from ('10.0.1.10', 37492)`

This leads me to believe that it is connecting on port 37492. I would like it
to connect on the port I tell it to, so I can port forward. Am I
misunderstanding, or is there an extra command to specify it.

Edit: I am uploading my code:

Client.py

    
    
    #!/usr/bin/python           # This is client.py file
    
    import socket               # Import socket module
    
    s = socket.socket()         # Create a socket object
    host = socket.gethostname() # Get local machine name
    port = 12345                # Reserve a port for your service.
    
    s.connect(("10.0.1.42", port))
    print s.recv(1024)
    s.close                     # Close the socket when done
    

Server.py

    
    
    import socket
    
    s = socket.socket()         # Create a socket object
    host = "10.0.1.42"          # Get local machine name
    port = 12345                # Reserve a port for your service.
    s.bind((host, port))        # Bind to the port
    
    s.listen(5)                 # Now wait for client connection.
    while True:
            c, addr = s.accept()     # Establish connection with client.
            print 'Got connection from', addr
            c.send('Thank you for connecting')
            c.close()                # Close the connection
    


Answer: You have reached that point in your networking life where you need to
understand protocol multiplexing. Good for you.

Think of the TCP/IP stack. An application communicates with a remote
application by passing application-layer data to the transport (end-to-end)
layer, which passes it to the network layer (internetwork layer) which tries,
without guarantees, to have packets reach the IP destination host over a
sequence of hops determined by cooperating routers that dynamically update
their routing tables by talking to connected routers. Each router conversation
goes over a physical transport of some kind (ISDN, Ethernet, PPP - in TCP/IP
the task of creating packets and transmitting the appropriate bit stream is
regarded as a single "subnetwork" layer, but this is ultimately split into two
when differentiation is required between the OSI physical layer (Layer 1) and
the data link layer (layer 2) for protocols like DHCP.

When TCP and UDP were designed, the designers imagined that each server would
listen on a specific port. This typically has the inherent limitation that the
port can only handle one version of your service protocol (though protocols
like HTTP take care to be backwards-compatible so that old servers/clients can
generally interoperate with newer ones). There is often a service called
portmapper running on port 111 that allows servers to register the port number
they are running on, and clients to query the registered servers by service
(program) number and protocol version. This is a part of the Sun-designed RPC
protocols, intended to expand the range of listening ports beyond just those
that were pre-allocated by standards. Since the preallocated ports were
numbered from 1 to 1023, and since those ports typically (on a sensible
operating system) require a high level of privilege, RPC also enabled non-
privileged server processes as well as allowing a server to be responsive to
multiple versions of network application protocols such as NFS.

However the server side works, the fact remains that there has to be some way
for the network layer to decide which TCP connection (or UDP listener) to
deliver a specific packet to. Similarly for the transport layer (I'll just
consider TCP here since it's connection-oriented - UDP is similar, but doesn't
mind losing packets). Suppose I'm a server and I get two connections from two
different client processes on the same machine. The destination (IP address,
port number) will be the same if the clients are using the same version of the
same protocol, or if the service only listens on a single port.

The server's network layer looks at the incoming IP datagram and sees that
it's addressed to a specific server port. So it hands it off to that port in
the transport layer (the layer above the network layer). The server, being a
popular destination, may have several connections from different different
client processes on the same machine. This is where the magic of ephemeral
ports appears.

When the client requests a port to use to connect to a service, the TCP layer
_guarantees_ that no other process on that machine (technically, that
interface, since different interfaces have unique IP addresses, but that's a
detail) will be allocated the same port number while the client process
continues to use it.

So protocol multiplexing and demultiplexing relies on five pieces of
information:

(sender IP, sender port, protocol, receiver IP, receiver port)

The protocol is a field in the IP header as are the source and destination IP
addresses. The sending and receiving port numbers are in the transport layer
segment header.

When an incoming packet arrives, the guaranteed uniqueness of different
ephemeral ports from the same client (endpoint) allows the transport layer to
differentiate between different connections to the same server IP address
_from_ the same client IP address and port (the worst case for demultiplexing)
by their source IP address and port. The (transport) protocol is included to
ensure that TCP and UDP traffic don't get mixed up. The TCP/UDP constraints on
uniqueness of ephemeral ports guarantee that any server can only receive one
connection from a specific combination of `(IP address, port number)` and it's
that that allows connections from the same machine to be demultiplexed into
separate streams corresponding to the different origins.

In Python when you connect a socket to a remote endpoint the `socket.accept()`
call returns the (IP address, port number) pair for the remote endpoint. You
can use that to discover who is communicating with you, but if you just want
to talk back you can simply `write()` the socket.

