首页 > 解决方案 > 为什么在尝试使用套接字发送字典时出现此错误:“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

感谢任何可以提供帮助的人。

标签: pythonpicklepython-sockets

解决方案


推荐阅读