0
votes

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))
1
I'll wait a few days before giving my answer a tick to see whether someone can give a better explanation.MAPster
stackoverflow.com/questions/14915380/… This seems to address the same issue in a different context. The solution was to use TCP since the socket is explicitly bidirectional. However TCP is due to the complex transfer mechanism not a good choice for a game (at least not for continous data transfer where packets are allowed to be lost)MAPster

1 Answers

0
votes

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 =)