I have currently a running server which is fully functional. But when I close down the server the server could not use the same port, because the socket has not been closed in the script so I have to manually do:
netstat -ano | findstr :portgoeshere and taskkill/pid portgoeshere /F
I do know that I need to use the following command to close the socket:
optionally use: .shutdown() and a required: .close()
This is the code of the server:
class Server:
ip = socket.gethostbyname(socket.gethostname())
def __init__(self,host = ip, port=portgoeshere):
self.socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
self.socket.setblocking(False)
self.socket.bind((host,port))
self.addr_user = {}
def receive(self):
while True:
try:
data, addr = self.socket.recvfrom(1024)
if not addr in self.addr_user:
user = User(data.decode())
scene = logic.getCurrentScene()
spawner = scene.objects["Spawner"]
avatar = scene.addObject("Avatar", spawner)
avatar.children[0]["Text"] = user.name
avatar["user"] = user
self.addr_user[addr] = user
else:
user = self.addr_user[addr]
data = pickle.loads(data)
user.keyboard.updateState(data[0])
user.mousePosition.updateMousePosition(data[1])
except socket.error:
break
def send(self):
scene = logic.getCurrentScene()
state = {(gobj.name, gobj["user"].name): [list(gobj.worldPosition),\
[gobj.worldOrientation.to_euler().x,gobj.worldOrientation.to_euler().y,gobj.worldOrientation.to_euler().z],\
[getChildren(gobj).worldOrientation.to_euler().x,getChildren(gobj).worldOrientation.to_euler().y,getChildren(gobj).worldOrientation.to_euler().z]] \
for gobj in scene.objects \
if gobj.name == "Avatar"}
for addr in self.addr_user:
#print(state)
self.socket.sendto(pickle.dumps(state),addr)
server = Server()
def receive(self):
server.receive()
def send():
server.send()
This is the code of the client:
class Client:
def __init__(self,server_ip ="ipgoeshere", server_port=portgoeshere):
self.socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
self.socket.setblocking(False)
self.serv_addr = (server_ip,server_port)
self.entities = {}
self.main = self.state_sendName
def state_sendName(self):
scene = logic.getCurrentScene()
text = scene.objects["Name"]
if keyHit(events.ENTERKEY):
self.socket.sendto(bytes(text["Text"],"utf-8"),self.serv_addr)
text.endObject()
self.main = self.state_loop
def state_loop(self):
self.send()
self.receive()
logic.mouse.visible = True
logic.mouse.position = 0.5,0.5
scene = logic.getCurrentScene()
scene.active_camera = scene.objects['AvatarCamera']
def send(self):
mouseMovement = logic.mouse.position
list_key_stat = []
kevts = logic.keyboard.events
for k in kevts:
s = kevts[k]
if s in (logic.KX_INPUT_JUST_ACTIVATED, logic.KX_INPUT_JUST_RELEASED):
list_key_stat.append((k,s))
if logic.mouse.position is not 0.5:
self.socket.sendto(pickle.dumps([list_key_stat,mouseMovement]),self.serv_addr)
def receive(self):
while True:
try:
data, addr = self.socket.recvfrom(1024)
state = pickle.loads(data)
for k in state:
if not k in self.entities:
scene = logic.getCurrentScene()
spawner = scene.objects["Spawner"]
entity = scene.addObject(k[0], spawner)
entity.children[0]["Text"] = k[1]
self.entities[k] = entity
else:
entity = self.entities[k]
entity.worldPosition = Vector(state[k][0])
entity.worldOrientation = Vector(state[k][1])
getChildren(entity).worldOrientation = Vector(state[k][2])
except socket.error:
break
client = Client()
This is some working code of a different client:
server = "ipgoeshere" #Het IP adres van de game
port = portgoeshere #Het poortnummer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waiting for connection on: ",server,":",port," Server started")
def read_pos(str):
str = str.split(",")
return int(str[0]), int(str[1])
def make_pos(tup):
return str(tup[0]) + "," + str(tup[1])
pos = [(0,0),(100,100)]
def threaded_client(conn, player):
conn.send(str.encode(make_pos(pos[player])))
reply = ""
while True:
try:
data = read_pos(conn.recv(2048).decode())
pos[player] = data
if not data:
print("Disconnected")
break
else:
if player == 1:
reply = pos[0]
else:
reply = pos[1]
print("Received : ", data)
print("Sending : ", reply)
conn.sendall(str.encode(make_pos(reply)))
except:
break
print("Lost connection")
conn.close()
currentPlayer = 0
while True:
conn, addr = s.accept()
print("Connected to:", addr)
This is what I want to happen:
Server: When the server gets shutdown the socket gets closed so I can use the same port again when I want to reinitialize the server.
Client: When the client gets shutdown I want the socket of (ONLY THE CLIENT) get closed so the server does not shutdown and the client could reconnect to the server when there are problems.