Multiplayer Script Test problem

Hey guys! I need some help with my experiment regarding sockets. I am trying to send a bunch of data through the Net using the port 5454. The sending of data was a success, but the receiving of data however was a failure. The console says that only one port can be used at a time, which kind of worried me. Here are the test scripts:

Server:


#A stream of data sendto my own computer
import socket
from bge import logic




HOST = "localhost"
PORT = 5454#Below 65000. Also, over 1024 since they are used for other services.
c = logic.getCurrentController()
keyB = logic.keyboard
keys = c.sensors["Keyboard"]
data = b"w"


soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)






if keys.positive:
    
    soc.sendto(data, (HOST, PORT))
    print ("sent" + str(data))



Client:


import socket
from bge import logic


HOST = "localhost"
PORT = 5454


soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)


soc.bind((HOST, PORT))


c = logic.getCurrentController()
always = c.sensors["Always"]


if always.positive:
    
    print(soc.recv(30))

This happens when the socket isn’t closed (the one bound to the port). Be sure to close the socket before quitting the game. If you want to simply fix this, close Blender and open it again.

Are you running this as a ‘script’ or as a ‘module’ (that’s a setting on your Python Controller). If you are running as a ‘script’ then it also looks like you are trying to bind to the listening port each frame.

Well, I modified it right now, but while the server module works extremely well, the client seems to suffer a problem with unblocked sockets. The console states that the unblocking method wasn’t completed. Here are the two modules again:

Server:


import socket
from bge import logic
import pickle


host, port = ["localhost", 30000]


#filepath = logic.expandPath("//")
#fp = filepath + "/" + ("game_network_data.txt")


def main():
    c = logic.getCurrentController()
    o = c.owner
    
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #s.bind((host, port))
    x, y, z = o.worldPosition
    yB = pickle.dumps(y)
    print(s.sendto(yB, (host, port)), pickle.loads(yB))
    s.close()

Client:


import socket
from bge import logic


def main():
    HOST = "localhost"
    PORT = 30000
    
    soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    soc.bind((HOST, PORT))
    soc.setblocking(0)
    c = logic.getCurrentController()
    o = c.owner
    always = c.sensors["Always"]
    if always.positive:
        print (str(soc.recvfrom(40)))
        try:
            data, addr = soc.recvfrom(40)
            print (data, addr)
        except socket.error as sErr:
            if sErr.errno == 10035:
                print(False)
        else:
            raise sErr
            
        
    soc.close()

Well, I have successfully run both the server and client, transmitting the location, and rotation of the server player to the client. The client then assigns that data to a cube. However, I have another strange problem. Whenever I quit the server, the client doesn’t quit; it is stuck in this recursive loop where the player cannot do anything (plus you can’t quit the BGE). I have been trying out different techniques, however, none of them ever work. I hope someone could read this and shed light on this.

Can you post your current code?

Client
http://www.pasteall.org/41217/python

Server
http://www.pasteall.org/41218

I haven’t added any catch for quit-game, so it will throw a port error when you run the script a second time

Well, I have solved the problem; by adding a timeout. This ‘quits’ the game if BGE loses patience with the port (he he). Here’s the current code:

Server:


#A stream of data sendto my own computer
import socket
from bge import logic, render
from pickle import dumps, loads
from time import sleep




def main():
    HOST = "localhost"
    PORT = 5454#Below 65000. Also, over 1024 since they are used for other services.
    
    c = logic.getCurrentController()
    o = c.owner
    
    isGameQuit = False
    datum = 
[list(o.worldPosition), isGameQuit, tuple(o.localOrientation.to_euler())]
    data = dumps(datum)
    
    soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    c = logic.getCurrentController()


    end = c.sensors["End"]
    always = c.sensors["Always"]
    render.showMouse(1)
    
    soc.sendto(data, (HOST, PORT))
    print ("sent" + str(loads(data)))
    if end.positive and always.positive:
        isGameQuit = True

Client:


import socket
from bge import logic, render
from pickle import loads
from mathutils import Vector


def main():
    c = logic.getCurrentController()
    o = c.owner
    HOST = "localhost"
    PORT = 5454
    
    soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    soc.bind((HOST, PORT))
    soc.settimeout(1.0)
    wP = loads(soc.recv(1024))
    o.worldPosition = Vector(wP[0])
    o.localOrientation = Vector(wP[1])
    print (wP)
    render.showMouse(1)
    soc.close()