3
votes

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.

1
It's not uncommon to see things in Wireshark and it still be broke. Wireshark allows all packets. Have you tried a for loop on the receiving end?Drewness
Even if you try to connect to your own internet-address it should work. This reminds me of UDP hole punching which I tried with a friend and it worked via the internet. We had different internet-addresses, though. Are you sure your router forwards all udp traffic from port 5000 to your computers port 5000? Maybe you can try to reach yourself from outside and from a different ip.User
Never unpickle random data from the internet. Read the warning at the top of docs.python.org/2/library/pickle.html.Jean-Paul Calderone

1 Answers

3
votes

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.