python - 为什么在尝试使用套接字发送字典时出现此错误:“EOFError: Ran out of input”?
问题描述
所以,我正在制作一个在线游戏,我正在尝试从服务器发送一个“射弹”对象。我可以从客户端发送字典,但是在将数据发送回客户端时无法发送,并且出现错误。
我按照 TechWithTim 的在线教程进行操作,并尝试将其调整到我的游戏中。
这是我的代码:
客户端代码.py
import pygame
from TWTNetwork import Network
from NewPlayerCode import Player,bullets
pygame.init()
width = 500
height = 500
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Client")
#bullets = []
def redrawWindow(win,player, player2,bullets,other_bullets):
win.fill((255,255,255))
player.draw(win)
player2.draw(win)
for bullet in bullets:
bullet.draw(win)
#for other_bullet in other_bullets:
# other_bullet.draw(win)
pygame.display.update()
def main():
run = True
n = Network()
p = n.getP()
clock = pygame.time.Clock()
other_bullets = []
dictionary = {}
while run:
clock.tick(60)
p2 = n.send(p)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
p.move()
for bullet in bullets:
if bullet.origin_x > 0 and bullet.origin_x <500 and bullet.origin_y > 0 and bullet.origin_y <500:
bullet.origin_x += bullet.x_vel
bullet.origin_y += bullet.y_vel
else:
bullets.pop(bullets.index(bullet))
## for bullet in other_bullets:
## if bullet.origin_x > 0 and bullet.origin_x <500 and bullet.origin_y > 0 and bullet.origin_y <500:
## bullet.origin_x += bullet.x_vel
## bullet.origin_y += bullet.y_vel
##
## else:
## other_bullets.pop(other_bullets.index(bullet))
#print(bullets)
#print(len(bullets))
if len(bullets) > 0:
number = 0
for bullet in bullets:
dictionary[number] = bullet
number +=1
other_bullets_dict = n.send(dictionary)
#for key in other_bullets_dict:
#other_bullets.append(data[key])
print(other_bullets_dict )
#bullet1 = n.send(bullet)
#other_bullets.append(bullet1)
print(dictionary)
# elif len(bullets) == 0:
#thing = n.send(len(bullets))
for bullet in bullets:
if bullet.origin_y - bullet.radius < p.hitbox[1] + p.hitbox[3] and bullet.origin_y + bullet.radius > p.hitbox[1]:
if bullet.origin_x - bullet.radius < p.hitbox[0] + p.hitbox[2] and bullet.origin_x + bullet.radius > p.hitbox[0]:
bullets.pop(bullets.index(bullet))
if bullet.origin_y - bullet.radius < p2.hitbox[1] + p2.hitbox[3] and bullet.origin_y + bullet.radius > p2.hitbox[1]:
if bullet.origin_x - bullet.radius < p2.hitbox[0] + p2.hitbox[2] and bullet.origin_x + bullet.radius > p2.hitbox[0]:
bullets.pop(bullets.index(bullet))
redrawWindow(win, p, p2,bullets,other_bullets)
main()
TWTNetwork.py
import socket
import pickle
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "192.168.1.106"
self.port = 5555
self.addr = (self.server, self.port)
self.p = self.connect()
def getP(self):
return self.p
def connect(self):
try:
self.client.connect(self.addr)
return pickle.loads(self.client.recv(4096))
except:
pass
def send(self, data):
try:
self.client.send(pickle.dumps(data))
#print(pickle.loads(self.client.recv(4096)))
return pickle.loads(self.client.recv(4096))
except socket.error as e:
print(e)
新播放器代码.py
import pygame
from ProjectileClass import projectile,bullet_rate,Pistol,AssultRifel,Sniper
class Player (object):
def __init__ (self, x, y, width, height, ammo, max_ammo):
self.x = x
self.y = y
self.width = width
self.height = height
self.ammo = ammo
self.max_ammo = max_ammo
self.health = 50
self.vel = 5
self.up= False
self.down= False
self.left= False
self.right= True
self.hitbox = (self.x -3 , self.y -3, 48, 48)
#These are some variables for the player
self.player_x_pos =0
self.player_y_pos = 0
self.player_pos = [self.player_y_pos, self.player_x_pos ]
self.shootLoop = 0
self.shooting_state = False
def draw (self,screen):
self.hitbox = (self.x -3 , self.y -3 , 48, 48)
#This will show the direction the player is facing
if self.up == True:
pygame.draw.rect(screen, (255,0,0), (self.x, self.y, self.width, self.height))
elif self.down == True:
pygame.draw.rect(screen, (0,255,0), (self.x, self.y, self.width, self.height))
elif self.left == True:
pygame.draw.rect(screen, (0,0,255), (self.x, self.y, self.width, self.height))
elif self.right == True:
#pygame.draw.rect(screen, (255,0,255), (self.x, self.y, self.width, self.height))
pygame.draw.rect(screen, (0,255,255), (self.x, self.y, self.width, self.height))
#Shows the ammo above the player
pygame.draw.rect(screen, (255,0,0), self.hitbox, 2)
font1= pygame.font.SysFont('comicsans', 18)
text = font1.render(str(self.ammo) + "/" + str(self.max_ammo), 1, (255,255,255))
screen.blit(text, (self.x, self.y - 10))
def move(self):
click = pygame.mouse.get_pressed()
mouse = pygame.mouse.get_pos()
#self.mouse_x = mouse[0]
#self.mouse_y = mouse[1]
keys = pygame.key.get_pressed()
#if pistol_gun == True:
Pistol()
self.shooting_rate = bullet_fire_rate
## elif ar_gun == True:
## AssultRifel()
## else:
## Sniper()
#and self.shootLoop == 0
if click[0] == 1 and self.ammo >= 1 and self.shootLoop == 0:
#https://www.fesliyanstudios.com/royalty-free-sound-effects-download/gun-shooting-300
pygame.mixer.music.load("Gunshot.mp3")
pygame.mixer.music.play()
#These if statements are to make the bullet spawn in a certain location relative to the self
#This resolves a problem where the self would end up shooting its self if it shot from the same place every time
if mouse[0] > self.x-60 and mouse[0]< self.x + self.width+50 and mouse[1]< self.y:
bullets.append(projectile((round(self.x + self.width //2)), (round(self.y + self.width //2)-35), mouse[0], mouse[1], bullet_speed , (0,0,0), bullet_radius ,bullet_damage,bullet_fire_rate))
self.up= True
self.down= False
self.left= False
self.right= False
#After each shot, it will show the direction of the self
elif mouse[0] > self.x -60 and mouse[0]< self.x + self.width+50 and mouse[1]> self.y+self.height:
bullets.append(projectile((round(self.x + self.width //2)), (round(self.y + self.width //2)+35), mouse[0], mouse[1], bullet_speed , (0,0,0), bullet_radius ,bullet_damage,bullet_fire_rate))
self.up= False
self.down= True
self.left= False
self.right= False
elif self.x < mouse[0]:
bullets.append(projectile((round(self.x + self.width //2)+30), (round(self.y + self.width //2)), mouse[0], mouse[1], bullet_speed , (0,0,0), bullet_radius ,bullet_damage,bullet_fire_rate))
self.up= False
self.down= False
self.left= False
self.right= True
elif self.x > mouse[0]:
bullets.append(projectile((round(self.x + self.width //2)-30), (round(self.y + self.width //2)), mouse[0], mouse[1], bullet_speed , (0,0,0), bullet_radius ,bullet_damage,bullet_fire_rate))
self.up= False
self.down= False
self.left= True
self.right= False
print("pew")
#Shooting_state allows for the user to walk backwards, shoot and still face the correct direction
self.shooting_state = True
#After each shot it will remove 1 ammo from the self's ammunition
self.ammo -=1
#This shootloop is to prevent the bullets firing all at once
self.shootLoop = 1
elif click[0] == 0:
self.shooting_state = False
#These change the position of the player depending on what key is pressed
if keys[pygame.K_a]:
self.x -= self.vel
#shows the direction of the player when they are not shooting
if self.shooting_state == False:
self.up= False
self.down= False
self.left= True
self.right= False
elif keys[pygame.K_d]:
self.x+= self.vel
if self.shooting_state == False:
self.up= False
self.down= False
self.left= False
self.right= True
elif keys[pygame.K_w] :
self.y -= self.vel
if self.shooting_state == False:
self.up= True
self.down= False
self.left= False
self.right= False
elif keys[pygame.K_s]:
self.y+= self.vel
if self.shooting_state == False:
self.up= False
self.down= True
self.left= False
self.right= False
elif keys[pygame.K_r]:
self.ammo = self.max_ammo
self.bullet_rate()
def bullet_rate(self):
if self.shootLoop > 0:
self.shootLoop += 1
if self.shootLoop > self.shooting_rate:
self.shootLoop = 0
bullets = []
def Pistol():
global bullet_speed ,bullet_radius, bullet_fire_rate,bullet_damage
bullet_speed = 10
bullet_radius =5
bullet_fire_rate =20
bullet_damage = 10
弹丸类.py
import math
import pygame
class projectile(object):
def __init__(self,origin_x, origin_y, go_to_x, go_to_y, speed, colour, radius, damage, fire_rate):
self.origin_x = origin_x
self.origin_y = origin_y
self.go_to_x = go_to_x
self.go_to_y = go_to_y
self.speed = speed
self.colour= colour
self.radius = radius
self.damage = damage
self.fire_rate = fire_rate
self.dx = self.go_to_x - origin_x
self.dy = self.go_to_y - origin_y
self.dist = max(1, math.hypot(self.dx, self.dy))
self.x_vel = self.speed * (self.dx/self.dist)
self.y_vel = self.speed * (self.dy/self.dist)
def draw(self, win):
#if the positions are not integers, it produces an error
pygame.draw.circle(win, self.colour, (int(self.origin_x), int(self.origin_y)), self.radius)
def bullet_rate(rate):
global shootLoop
if shootLoop > 0:
shootLoop += 1
if shootLoop > rate:
shootLoop = 0
def Pistol():
global bullet_speed ,bullet_radius, bullet_fire_rate,bullet_damage
bullet_speed = 10
bullet_radius =5
bullet_fire_rate =20
bullet_damage = 10
def AssultRifel():
global bullet_speed ,bullet_radius, bullet_fire_rate,bullet_damage
bullet_speed = 10
bullet_radius =5
bullet_fire_rate =10 #fire rate of 5 is op
bullet_damage = 10
def Sniper():
global bullet_speed ,bullet_radius, bullet_fire_rate,bullet_damage
bullet_speed = 20
bullet_radius =7
bullet_fire_rate =30
bullet_damage = 50
服务器2.py
这就是我认为问题所在(在 elif == 0: 部分) import socket from _thread import * from NewPlayerCode import Player,bullets import pickle import time
server = "192.168.1.106"
port = 5555
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 a connection, Server Started")
game_data = [[Player(0,0,50,50,30,30), Player(100,100, 50,50, 30,30)],[],[]]
def threaded_client(conn, player):
conn.send(pickle.dumps(game_data[0][player]))
reply = ""
data_to_send = []
bullet_dict = {}
dictionary = {}
number = 0
while True:
print(game_data)
try:
data = pickle.loads(conn.recv(4096))
string_data = str(data)
print(string_data[1],string_data[2])
if string_data[1] == "N" and string_data[2] == "e":
game_data[0][player] = data
else:
print("\n\n\n\n\n")
print(data)
for key in data:
print("\n\n\n\n\n",data[key])
game_data[player+1].append(data[key])
if not data:
print("Disconnected")
break
else:
if player == 1 and string_data[1] == "N" and string_data[2] == "e":
reply = game_data[0][0]
bullet_data = game_data[1]
print("player 1")
elif player == 0 and string_data[1] == "N" and string_data[2] == "e":
reply = game_data[0][1]
bullet_data = game_data[1]
print("player 2")
elif player == 2 and string_data[1] == "N" and string_data[2] == "e":
reply = game_data[0][2]
print("player3")
elif player == 0:
number2 = 0
for i in game_data[1]:
dictionary[number2] = bullet
number2 +=1
reply = dictionary
elif player == 1:
number2 = 0
for i in game_data[2]:
dictionary[number2] = bullet
number2 +=1
reply = dictionary
print("Received: ", data)
print("Sending : ", reply)
conn.sendall(pickle.dumps(reply))
except:
break
print("Lost connection")
conn.close()
currentPlayer = 0
while True:
conn, addr = s.accept()
print("Connected to:", addr)
start_new_thread(threaded_client, (conn, currentPlayer))
currentPlayer += 1
完全错误
回溯(最后一次调用):文件“C:\Users\tomfe\AppData\Local\Programs\Python\Python37-32\ClientCode.py”,第 101 行,在 main() 文件“C:\Users\tomfe\ AppData\Local\Programs\Python\Python37-32\ClientCode.py”,第 76 行,在 main other_bullets_dict = n.send(dictionary) 文件“C:\Users\tomfe\AppData\Local\Programs\Python\Python37-32 \TWTNetwork.py",第 89 行,在发送中返回 pickle.loads(self.client.recv(4096)) EOFError: Ran out of input
感谢任何可以提供帮助的人。
解决方案
推荐阅读
- google-app-engine - App Engine 中 Google Analytics API 的自动身份验证
- python-3.x - 如何更新腌制文件的权重?
- c# - 如何检测哪个 GPU 在 C# 中运行我的程序?
- c - C中4x4矩阵的奇异值分解
- python - 在 fastapi 中处理令牌过期
- tableau-api - Tableau 24 小时窗口
- openscad - 向openscad倒刺对象添加角度/角度轮廓
- reactjs - 与reactjs中antd表中的搜索输入结果相比,如何更新我的标题组件?
- javascript - 将值添加到 FOR 循环内的数组中的对象
- laravel - Laravel Breeze Vue - 链接和页面未呈现