I’m trying to setup a proper connection between server and client that allows the server to not only receive but also to send back data to the client.
Here’s what I have so far:
Client
import socket
import pickle
import bge
server = "localhost"
port = 27080
co = bge.logic.getCurrentController()
game = co.actuators['Game']
net = co.owner
if(net['init']==1):
try:
net['clientTCP'] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
net['clientUDP'] = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
net['clientTCP'].connect((server,port))
try:
beat = pickle.load(net['clientTCP'].recv(1))
id = pickle.load(net['clientTCP'].recv(1))
except:
beat = -1
id = -1
if(beat==-1 and id==-1):
net['error'] = 1
print("Unable to pickle.")
net['clientUDP'].bind(("",port+1))
net['clientUDP'].setblocking(0)
net['init'] = 0
print("Connected. Sending data.")
except:
print("Connection to server could not be made.")
net['error'] = 1
net['init'] = 0
elif(net['error']==0):
data = 1
while data is not 0:
try:
data, addr = net['clientUDP'].recvfrom(256)
try:
pickle.load(data)
except:
print("Can't pickle: ",data)
except:
data = 0
if(data is not 0): print(data)
else:
print("Data not sent because server timed out or is offline.")
co.activate(game)
Server
import socket
port = 27080
clients = []
print("Apollox Iteration 0000
")
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", port))
server.listen(1)
print("Server started on port ",port)
except:
print("Apollox could not initialize the server.")
input("Press Enter to quit.")
while 1:
(client, addr) = server.accept()
print(addr[0],":",addr[1]," connected.")
try:
i = clients.index(addr)
except:
print(client)
try:
client.send("0")
except:
print("FUCKING HELL!",client)
try:
udpSock = socket(AF_INET,SOCK_DGRAM)
udpSock.setblocking(0)
except:
print("Failed to create udpSock")
try:
clients.append([client,udpSock,addr])
except:
print("Cannot append. Invalid/Nonexistant data given.")
client.close()
print(clients)
The server runs via the Python console while the client code is run from inside Blender.
Currently it seems to be unable to send data back to the client (as in sending a handshake’ish thing).
I’m not really using pickle for anything yet.
If anyone knows how to properly setup a network, please let me know.
I’ve been trying to study the templates and other documents but most of them are outdated or simply don’t work in the way I want my server and clients to work.
Let me first show you some useful code.
Instead of just using try: except:
modify the exept statement after ‘client.send’ so that it now reads:
except Exception as error:
Exception is capitalised first letter.
Now, print(Exception) after the client.send.
Additionally, in the part of the server which creates a connection, you’ve typed:
udpSock = socket(AF_INET,SOCK_DGRAM)
should it not be:
udpSock = socket.socket(AF_INET,SOCK_DGRAM)
You will not know what statement produced the error.
using “net[‘clientUDP’]”
all the time means each statement is a search in the dictionary. The python access is quite fast, but this is not necessary to do that.
The code structure means the client sends data only once.
This is because the sending is in the init block.
Finally the socket connection is not closed after usage.
I suggest to separate connection handling from sending:
e.g.
openConnection()
sendData()
closeConnection()
“is 0”
For not existing data use None rather than 0 (None exist for exactly this case ;))
port = 27080
Better read the connection parameters (host, port) from properties rather than force the user to change the code.
“While 1:”
I can’t see you ever exit from the loop. (And never create an endless loop in the BGE!)
The server is running outside of Blender yes.
The ‘port’ variable is just temporary.
I’m now also using the logging module on the server side but it’s messy.
I’ve fixed the client.send issue. I had to encode the data to bytes.
Still I can’t get my head around it.
Does anyone of you know a good example of networking in Blender 2.6?
I would like it to be just a server and allow clients to connect to that and receive data from it. So no P2P in general.
I took a look at a link in agoose77’s signature but the tutorial on his website leads to a 404 page.
Sorry about the link, ill fix it. -> here is the page. http://hostilestudios.com/networking/tutorials/basic.php
Here is some easy UDP code.
You can expand this to make it dynamic, by having the server save the connecting client’s connection (called conn in the recvfrom part of the server) and send to that, as well as creating a new connection dedicated just for that client.
import bge
import socket
import pickle
def server(cont):
own = cont.owner
port = 1000
def init():
connection = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
connection.bind(('127.0.0.1', port))
connection.setblocking(0)
print('Server started')
own['connection'] = connection
if not 'connection' in own:
init()
connection = own['connection']
try:
data, conn = connection.recvfrom(1024)
print(pickle.loads(data))
except Exception as e:
pass #no data received
def client(cont):
own = cont.owner
port = 1010
server_ip = '127.0.0.1'
server_port = 1000
def init():
host = (server_ip, port)
connection = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
connection.bind(host)
connection.setblocking(0)
print('Client Connected')
own['host'] = host
own['connection'] = connection
if not 'connection' in own:
init()
host = (server_ip,server_port)
connection = own['connection']
if bge.logic.keyboard.events[bge.events.SPACEKEY]==1:
data = pickle.dumps(('Hello Mr Server'))
connection.sendto(data,host)