python server-client nat traversal -
i've done reading on udp nat traversal, , i'm reasonably confident understand basics i'm still struggling implementation.
my project has globally accessible server, , clients behind nat. game, basic join_game request send client server, , server sends out updates every interval. i've been testing @ home, , forgotten have dmz on router turned on worked fine. sent friends test , cannot receive updates server.
here current methodology, packets udp:
- client opens socket, , sends join request server.
- server gets request , reply-to address of message, , replies client: yes can join, , way sending updates reply-to ip/port looks this.
- client catches reply closes socket, , starts udp threaded listener class listen reply-to port server told about.
- client catches server updates flooded over, , processes them required. every , client opens new socket , sends udp packet update server (what keys pressed etc).
my understanding reply-to address server receives should have correct port traversing client's nat. , sending packets down there enough keep nat traversal rule alive.
this not happening. client sends join request, , receives server's response on socket. when close socket start threaded udp listener on reply-to port, doesn't catch anything. if traversal rule valid single response packet.
i can include code if needed, honest several layers classes , objects , described above. code works when turn dmz on, not when off.
i include snippets of interest.
here server's handler join request. client_address passed down threaded handler, , socketserver.baserequesthandler attribute, self.client_address. no parsing, passed down.
def handle_player_join(self, message, reply_message, client_address): # create player id player_id = create_id() # add player connected nodes dict self.modules.connected_nodes[player_id] = client_address # create player ship entity self.modules.players[player_id] = self.modules.factory.player_ship( position = (320, 220), bearing = 0, ) # set reply ack, , include player id , listen port reply_message.body = message.ack reply_message.data['player_id'] = player_id reply_message.data['listen_port'] = client_address[1] print "player joined :"+str(client_address)+", id: "+str(player_id) # return reply message return reply_message
a friend has mentioned maybe when send join request, response shouldn't close socket. keep socket alive, , make listener. i'm not convinced closing socket have effect on nat traversal, , don't know how spawn threaded udp listener takes pre-existing socket without rewriting whole damn thing (which i'd rather not).
any ideas or info required?
cheers
you can 1 of 2 things make code work. are,
don't close socket have sent packets server. when create socket binds private ip:port. when send packet server ip:port translated nats 1 public ip:port. when close socket data server comes first nats public ip:port , forwarded private ip:port. socket closed no 1 receive data. server has no way know have created new socket new private ip:port because never sent packet server after creating new socket. don't close old socket. try listen old 1 in thread. or can send packet server new socket letting know new translatedpublic ip:port. server can send data new public ip:port in turn forwarded new private ip:port.
close socket reuse same port. when close old socket , create new socket, bind port on old socket bound. not change nats public ip:port , data server not interrupted.
Comments
Post a Comment