Search code examples
pythonsocketstcp

Python Basic Client Server Socket Programs


I tried the basic programs for client and server from realpython (https://realpython.com/python-sockets/#echo-client-and-server)

While these work fine when running on the same computer, there is following problem when trying on different machines:

ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it

Client code:


HOST = '10.0.0.55'   # The server's hostname or IP address
PORT = 65432        # The port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Received', repr(data)) 

Server Code:

import socket

HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = 65432        # Port to listen on (non-privileged ports are > 1023)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

  • I can make pings from one computer to the other.
  • Firewall is turned down
  • Wireshark shows that the SYN message arrives on the second computer which is answered by a RST message (Wireshark PC server)

Solution

  • If you want the server to be open to other computers, you can't listen on 127.0.0.1 which is basically an inner local loop only located on the computer running the program (that's why it's called loopback in comments). You should have the server listen on its own real address (for example: 10.0.0.55 explicitly).

    This however can be annoying if your host can change addresses, an easy workaround is to just use the local IP address like this (on the server):

    HOST = socket.gethostbyname(socket.gethostname())
    

    Or if you specifically want to use the address from one network interface:

    HOST = '10.0.0.55'
    

    Or, if you want to listen on all network interfaces:

    HOST = '0.0.0.0'