Я учусь создавать сервер в Python для игры.
В конце концов, мы вводим это l oop ниже. Я заменил несвязанный код комментариями для презентации. Он работает непрерывно, пока не будет получен определенный ответ от сервера (if split_reply[2] == "established":
) или пока игрок не нажмет кнопку, чтобы перевести их в предыдущее меню.
def app_host():
server_started = False
connective_state = 'none'
connect = True
# stuff happening
while connect:
if not server_started:
server = Server()
host_address, host_port = server.get_host()
server_started = True
connective_state = 'host'
net = Network(host_address, host_port)
else:
client_word = str(net.id) + ":" + "connective state" + ":" + connective_state
reply = net.send(client_word)
split_reply = reply.split(":")
if split_reply[0] == net:
if split_reply[2] == "established":
connective_state = "established host"
app_setup()
# other stuff happening
if intro:
app_intro()
Класс сервера следующий:
class Server:
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.currentId = "0"
self.connective_states = ["none", "none"]
self.server_ip = socket.gethostbyname(socket.gethostname())
try:
self.s.bind((self.server_ip, 0)) # Binding to Port 0 allows the OS to select an available port
except socket.error as e:
print(str(e))
self.server_port = self.s.getsockname()[1]
self.s.listen(2)
print(f"Server hosted on {self.server_ip}:{self.server_port}.")
thread = threading.Thread(target=self.run_server, args=())
thread.daemon = True # Daemonize thread (if the game exits, shut down the server)
thread.start()
def run_server(self):
while True:
conn, addr = self.s.accept()
print(f"Connected to {addr[0]}:{addr[1]}.")
start_new_thread(self.threaded_client, (conn,))
def get_host(self):
return self.server_ip, self.server_port
def threaded_client(self, conn):
conn.send(str.encode(self.currentId))
currentId = "1"
while True:
try:
data = conn.recv(2048)
reply = data.decode('utf-8')
if not data:
conn.send(str.encode("Goodbye"))
break
else:
print("Received: " + reply)
split_reply = reply.split(":")
socket_id = int(split_reply[0])
# The ifs below should have no effect on this issue, you can ignore them
if split_reply[1] == "connective state":
self.connective_states[socket_id] = split_reply[2]
if self.connective_states == ["host", "client"] or ["client", "host"]:
#if "host" in connective_states and "client" in connective_states:
print(f"Connective states are: {connective_states}")
reply = str(socket_id) + ":" + "connective state" + ":" + "established"
print(reply)
print("Connection established !")
elif split_reply[1] == "socket":
if split_reply[2] == "disconnect":
print(f"Received request to disconnect socket {split_reply[0]}.")
conn.close()
conn.sendall(str.encode(reply))
except:
break
print("Connection Closed")
conn.close()
Сетевой класс:
class Network:
def __init__(self, address, port):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.host = address
self.port = port
self.addr = (self.host, self.port)
self.id = self.connect()
def connect(self):
self.client.connect(self.addr)
return self.client.recv(2048).decode()
def send(self, data):
try:
self.client.send(str.encode(data))
reply = self.client.recv(2048).decode()
return reply
except socket.error as e:
return str(e)
Во-первых, я использовал серверный класс в качестве скрипта, с threaded_client(conn)
в качестве единственной функции, выполняемой как подпроцесс; и это будет работать нормально. Этот метод, тем не менее, каким-то образом достигает конца (print("Connection Closed")
и закрывает соединение.
Почему это так?