У меня сейчас работает сервер, который полностью функционален.Но когда я закрываю сервер, сервер не может использовать тот же порт, потому что сокет не был закрыт в скрипте, поэтому я должен сделать вручную:
netstat -ano |findstr: portgoeshere и taskkill / pid portgoeshere / F
Я знаю, что мне нужно использовать следующую команду, чтобы закрыть сокет:
опционально используйте: .shutdown () и обязательно: .close ()
Это код сервера:
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()
Это код клиента:
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()
Это рабочий код другого клиента:
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)
Это то, что я хочуслучиться:
Сервер: Когда сервер отключается, сокет закрывается, поэтому я могу снова использовать тот же порт, когда я хочу повторно инициализировать сервер.
Клиент: Когда клиент выключается, яхотите, чтобы сокет (ТОЛЬКО КЛИЕНТА) был закрыт, чтобы сервер не выключался и клиент мог повторно подключиться к серверу при возникновении проблем.