Сначала я хочу показать весь код
main.py Это клиентская сторона.
import pygame, sys
import random
from newconstants import *
from components import *
from network import *
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Client")
def redrawWindow(win, walls, s1,a):
win.fill((173, 216, 230))
for w in walls:
w.draw(win)
s1.draw(win)
a.draw(win)
pygame.display.update()
def main():
main_run = True
game_run = True
menu_run = True
clock = pygame.time.Clock()
while main_run:
while menu_run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
menu_run = False
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN :
if event.key == pygame.K_RETURN:
try:
n = Network()
except Exception as e:
print(e)
pygame.quit()
sys.exit()
id = n.game.id
G = n.game.g
print(id)
while True:
try:
n.game = n.send(n.game)
except Exception as e:
print(e)
break
if n.game.ready:
break
s1 = n.game.snake[id]
s2 = n.game.snake[1 - id]
menu_run = False
# Making Walls and partitions
walls = [wall(0,0,width, wall_thickness,wall_color),
wall(0,0,wall_thickness,height,wall_color),
wall(0,height-wall_thickness,width,wall_thickness,wall_color),
wall(width-wall_thickness,0,wall_thickness,height,wall_color)]
start_x = wall_thickness
start_y = wall_thickness
while start_x < width - wall_thickness-cell_thickness:
start_x += cell_thickness
# Vertical wall
vw = wall(start_x,wall_thickness,partition_thickness,height-(2*wall_thickness),partition_color)
walls.append(vw)
start_x += partition_thickness
while start_y < height - wall_thickness-cell_thickness:
start_y += cell_thickness
# Horizontal wall
hw = wall(wall_thickness,start_y,width-(2*wall_thickness),partition_thickness,partition_color)
walls.append(hw)
start_y += partition_thickness
a = Apple(G)
while game_run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_run = False
pygame.quit()
sys.exit()
s1.check_collision(a)
s1.move()
redrawWindow(win,walls,s1,a)
main()
server.py Это мой код сервера
import socket, pickle
from _thread import *
from components import *
server = socket.gethostname()
port = 5555
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
print("Socket created")
try:
s.bind((server , port))
except socket.error as e:
str(e)
s.listen()
print("Waiting for connection Server started")
connected = set()
games = {}
id_count = 0
G = Grid(rows,cols)
start_x = wall_thickness
start_y = wall_thickness
for i in range(0 , G.rows):
for j in range(0, G.cols):
G.grid[i][j] = cell(start_x , start_y, cell_thickness,cell_thickness)
start_x += cell_thickness + partition_thickness
start_x = wall_thickness
start_y += cell_thickness + partition_thickness
def threaded_client(conn, p, game_id):
global id_count, games
if p == 0 :
games[game_id].snakes[p] = Snake(random.randint(3,rows//2),random.randint(3,cols//2),snake_head_width,snake_head_height,random.choice(clr_list_1),random.choice(headings),G)
else:
games[game_id].snakes[p] = Snake(random.randint(rows//2 + 1, rows - 4),random.randint(cols//2 +1,cols - 4),snake_head_width,snake_head_height,random.choice(clr_list_2),random.choice(headings),G)
games[game_id].g = G
games[game_id].id = p
initial_data = pickle.dumps(games[game_id])
initial_data = bytes(f"{len(initial_data):<{HEADERSIZE}}" , "utf-8")+initial_data
conn.send(initial_data)
reply = ""
while True:
try:
# recv data
full_msg = b""
new_msg = True
while True:
msg = conn.recv(1024)
if new_msg:
msglen = msg[:HEADERSIZE]
new_msg = False
full_msg += msg
if len(full_msg)-HEADERSIZE == msglen:
g = pickle.loads(full_msg[HEADERSIZE:])
break
games[game_id] = g
if game_id in games:
game = games[game_id]
if not recieved_data:
break
else:
# Send data
data = pickle.dumps(games[game_id])
data = bytes(f"{len(data):<{HEADERSIZE}}" , "utf-8")+data
conn.send(data)
else:
break
except Exception as e:
print(e)
break
print("Lost connection")
try:
del games[game_id]
print("Closing Game", game_id)
except:
pass
id_count -= 1
conn.close()
while True:
try:
conn , addr = s.accept()
print("Connnected to " , addr)
id_count += 1
p = 0
game_id = (id_count - 1) // 2
if id_count % 2 == 1:
games[game_id] = Game(game_id)
print("Creating a new game")
else:
games[game_id].ready = True
print("Joing on going game")
p = 1
start_new_thread(threaded_client , (conn , p, game_id))
except KeyboardInterrupt as e:
if conn: # <---
conn.close()
break # <---
network.py Это класс сети, который клиент использует для подключения к серверу
import socket, pickle
from newconstants import *
class Network():
def __init__(self):
self.client = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
self.server = socket.gethostname()
self.port = 5555
self.addr = (self.server , self.port)
self.game = self.connect()
def connect(self):
try:
self.client.connect(self.addr)
full_msg = b""
new_msg = True
while True:
msg = self.client.recv(1024)
if new_msg:
msglen = msg[:HEADERSIZE]
new_msg = False
full_msg += msg
if len(full_msg)-HEADERSIZE == msglen:
self.game = pickle.loads(full_msg[HEADERSIZE:])
break
return self.game
except Exception as e:
print("couldn't connect" , e)
def send(self, send_data):
try:
data = pickle.dumps(send_data)
data = bytes(f"{len(data):<{HEADERSIZE}}" , "utf-8")+data
self.client.send(data)
full_msg = b""
new_msg = True
while True:
msg = self.client.recv(1024)
if new_msg:
msglen = msg[:HEADERSIZE]
new_msg = False
full_msg += msg
if len(full_msg)-HEADERSIZE == msglen:
self.game = pickle.loads(full_msg[HEADERSIZE:])
break
return self.game
except Exception as e:
print(e)
Есть еще один файл в котором есть все классы, определенные для создания вещей в pygame, не важных для проблемы, но дайте мне знать, если вам это нужно
Теперь я запускаю сервер, он работает нормально, и соединения acepts Затем я запускаю клиент, который он запускает, а затем, вы можете видеть мы должны нажать клавишу ввода, чтобы фактически начать соединение, поэтому, когда я нажимаю клавишу ввода, все застревает. Поскольку эта игра требует, чтобы два клиента делали то же самое с двумя клиентами, результаты не резонируют. На стороне сервера игра создается первым клиентом, а второй клиент подключается, после этого ничего не происходит. Если я принудительно закрываю сервер, я получаю ошибку, указанную ниже
[Errno 9] Плохой дескриптор файла. Потеряно соединение. Неустранимая Python ошибка: не удалось получить блокировку для <_io.BufferedWriter name = ''> в завершение работы интерпретатора, возможно из-за потоков демона Python состояние выполнения: завершение (tstate = 0x173af10)
Поток 0x00007fca7be8e700 (сначала последний вызов): файл «server.py», строка 99 в thread_client
Текущий поток 0x00007fca82c7b740 (сначала последний вызов): Прервано (дамп ядра)
Так что я делаю не так ?? Я вообще этого не понимаю. Пожалуйста, дайте мне знать, если вам нужно что-то еще для решения проблемы. Я впервые работаю с потоками и сокетами, поэтому я новичок ie в этом ваша помощь будет огромной.
Спасибо!