Question

The last couple of days I spent trying to figure out how to send data back and forth via UDP (I have plans for a simple multiplayer game). So far so good, until I realized it only works fine over LAN but none of the packets ever arrive over internet. If I run the test server and test script (code is below) on one computer and send data over LAN it arrives just fine (Wireshark spews out an "Port unreachable" error when sending over internet). When I have client and server on different computers I can send data over internet and LAN, nothing ever arrives at the destination. I spent hours googling, made sure ports are forwarded, fiddled with settings, double- and triple-checked the code, checked with Wireshark, tested with other people, nothing.

What am I doing wrong?

Here my test code:

import socket, pickle
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.setblocking(0)
port = 5000

type = raw_input("1=Server 2=Client 3=Local Client: ")

if type == "1":
  ip = ""
  sock.bind((ip,port))
  print("Socket: "+str(sock.getsockname()))
  while True:
    try:
      rdata, addr = sock.recvfrom(1024)
      data = pickle.loads(rdata)
      print addr, ">>>", data
    except:
      pass

elif type == "2":
  ip = "79.222.132.25"
  sock.bind(("192.168.2.102",port+1))
  sock.connect((ip,port))
  print("Socket: "+str(sock.getsockname()))
  print("Connected to: "+str(sock.getpeername()))
  while True:
    input = raw_input("Send:")
    data = pickle.dumps((input))
    sock.send(data)

else:
  ip = "192.168.2.102"
  sock.bind((ip,port+1))
  while True:
    input = raw_input("Send:")
    data = pickle.dumps((input))
    sock.sendto(data,(ip,port))

Thanks for help in advance.

Was it helpful?

Solution

I just ran your code, through Internet, and works fine. I used type 1 and 2 to test. Firstly, I recommend you to remove the line binding port in Client. Like this:

elif type == "2":
ip = "79.222.132.25"
# sock.bind(("192.168.2.102",port+1))
sock.connect((ip,port))
print("Socket: "+str(sock.getsockname()))
print("Connected to: "+str(sock.getpeername()))
while True:
    input = raw_input("Send:")
    data = pickle.dumps((input))
    sock.send(data)

Because usually a client don't need to explicitly bind port -- when calling sock.connect(), system will automatically assign a random port to your socket.

Then let's solve your problem. Your code is correct, so there must be something wrong with the Internet, more likely the server. If your server is working under a NAT gateway or an router, any incoming connection will be refused by your gateway. An easy way to test your server's status, is typing ipconfig (or ifconfig in Linux) in command line prompt to check whether the local IP address is the public Internet address. Public Internet address can retrieve from this website: whatismyipaddress.com.

This is the most possible problem you may encounter. An easiest way to make server's networking environment correct, is to find a real server, which has static public IP, and without any NAT gateway. Or just rent a VPS to test your code.

Thanks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top