What I wanted to do:
For learning about game programming I created an echo setup using a dedicated server and UDP. The dedicated server is in a different city (aka NOT in my local network).
On my local computer I have a udp client and server ( 2 different programs ). When I first started my python server I was immediately asked by windows firewall whether I want to add an exception. After allowing networking for my python server, I still did not receive any messages. (client -> dedicated server -/-> local server )
Only after I set a port forwarding in my router I was able to receive messages on my local UDP server.
My question is:
How do games solve that problem ? I don't activate a port forwarding for each multiplayer game I want to play and I'm still able to receive data in all these games.
My dedicated server setup (address and port intentionally changed):
#!/usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
serverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
serverSock.bind((ADDRESS, PORT))
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addresses = []
while True:
data, addr = serverSock.recvfrom(1024)
if addr not in addresses:
addresses.append(addr)
msg = str(data)
#if msg.split()
print("Message: " + str(data))
outMsg = str(addr) + ":" + msg
for ad in addresses:
print("Send Msg " + outMsg + " to " + ad[0] + ":" + str(PORT))
clientSock.sendto(bytes(outMsg, "utf-8"), (ad[0], 12345))
print("Addresses: " + str(addresses))
I figured this one out while writing up the question (like talking to the good old rubber duck):
The trick is not using 2 programs on the local computer. The program that sends the message also needs to retrieve the message. In my example it's blocking calls (ugly!), for a game you'd want to make that asynchronous. But this is the simplest way to get around the router firewall:
#! /usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# usually not required to bind a client, but we want to receive messages
clientSock.bind(("0.0.0.0",PORT))
while True:
msg = input("Enter message: ")
# Note that it is not required to send to the same port
# you have locally binded to.
clientSock.sendto(bytes(msg, "utf-8"), (ADDRESS, PORT))
# listen to the echo:
data, addr = clientSock.recvfrom(1024)
print(str(data) + " from " + str(addr))
However, my understanding on sockets and firewalls is limited. I do not understand why THIS works but 2 separated programs don't. Maybe someone could comment on that. Hope I can save someone some time =)