Below I have two scripts that work when I bind the server.py to my computers IPV4 address and connect the client.py to that same address. The next step I'm trying to take is the ability to use this socket across different networks. I thought that it would be as simple as changing the value of SERVER to my public IP address (which can be found by clicking this link). When I make that change, I get this error upon running server.py:
Traceback (most recent call last):
File "C:\Users\gmbra\Downloads\Python Programs\Concepts\Sockets\server.py", line 13, in <module>
server.bind(ADDRESS)
OSError: [WinError 10049] The requested address is not valid in its context
server.py
import socket
import threading
PORT = 5050
# SERVER = '192.168.0.30'
SERVER = socket.gethostbyname(socket.gethostname()) # Change this to the public IP address to allow access across multiple networks
ADDRESS = (SERVER, PORT)
HEADER = 64 # The number of bytes expected to get from the client
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET is the type of addresses we are looking for
server.bind(ADDRESS)
def handle_client(conn, address):
print(f"[NEW CONNECTION] {address} connected.")
while True:
msg_length = conn.recv(HEADER).decode(FORMAT) # This line also blocks until it receives a message
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
conn.close()
break
print(f'[{address}] {msg}')
conn.send("Message Received".encode(FORMAT))
def start():
server.listen()
print(f'[LISTENING] Server is listening on {SERVER}.')
while True:
conn, address = server.accept() # This line will wait until it finds a connection.
thread = threading.Thread(target=handle_client, args=(conn, address))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 1}.")
print("[STARTING] Server is starting...")
start()
client.py
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = '!DISCONNECT'
SERVER = "192.168.0.30"
ADDRESS = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDRESS)
# The pickle module could be used to send objects instead of strings.
def send(msg):
message = msg.encode(FORMAT)
# For some reason we have to send a byte string first with the integer size of the message, concatenated with spaces
# until it hits the length of the header.
send_length = str(len(message)).encode(FORMAT)
send_length += b' '*(HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
while True:
message_ = input('Message: ')
send(message_)
if message_ == "!DISCONNECT":
break
What must I do to make this work across different networks?
SERVERto''inserver.pyto indicate that the port should be accessible from any of the server's networks. (note that if your PC is behind a firewall, the firewall will still block incoming TCP connection as usual, though)