我正在尝试构建一个使用套接字和udp协议的python在线游戏。我创建了一个多处理和多线程服务器:https://pastebin.com/zucxwpc9。
import socket
import multiprocess
def new_lobby(port, addr1, addr2):
import socket
import Queue
import threading
address1 = addr1
address2 = addr2
local_ip = ""
local_port = port
buffer_size = 1024
print(port)
sock = socket.socket(family = socket.AF_INET, type = socket.SOCK_DGRAM)
sock.bind((local_ip, local_port))
sock.settimeout(10)
running = True
q = Queue.Queue(10000)
print ("before threads")
def listen(sock):
running = True
buffer_size = 1024
while running:
try:
data_address = sock.recvfrom(buffer_size)
except socket.timeout:
running = False
q.put(data_address)
def send(sock, address1, address2):
while True:
data_address = q.get()
if data_address[1] == address1:
sock.sendto(data_address[0], address2)
else:
sock.sendto(data_address[0], address1)
thread1 = threading.Thread(target = listen, args=(sock, ))
thread2 = threading.Thread(target = send, args = (sock, address1, address2))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
local_ip = ""
local_port = 10001
buffer_size = 1024
server_message = "connected"
byte_server_message = str.encode(server_message)
sock = socket.socket(family = socket.AF_INET, type = socket.SOCK_DGRAM)
sock.bind((local_ip, local_port))
lobby = []
port_count = 10002
check_alive = False
while True:
message, address = sock.recvfrom(buffer_size)
message = message.decode("utf-8")
print(address, " ", message)
if address not in lobby:
lobby.append(address)
if len(lobby) == 2:
p = multiprocess.Process(target = new_lobby, args = (port_count,lobby[0], lobby[1]))
p.start()
port = str(port_count)
port = port.encode()
for address in lobby:
print(address)
sock.sendto(port,address)
port_count += 1
lobby = []
check_alive = True
if check_alive:
print(p.is_alive())
我会解释里面的代码是做什么的。所以首先,它等待两个请求,并将它们放入lobby列表中。如果发出了两个请求,服务器将向客户端发送一个新端口,并创建一个具有两个线程的新进程。两个线程都在使用新端口,一个接收数据,另一个发送数据。我正在使用队列,这样我就可以跟踪数据,避免在相同的时间内使用相同的资源。客户端是一个pygame游戏。我做了一个小的测试游戏方块移动的地方,鼠标的位置。https://pastebin.com/qdku6rij.我有一个连接类,我把它放在游戏的init中。起初,我也使用多线程连接,但我观察到它运行得非常慢(我不认为这是线程错误,但我真的不知道)。因此,curent connection类与主服务器连接,等待发送端口,并用两个线程启动新进程:一个线程监听数据,另一个线程正在发送。我也在其中使用了一个队列,尽管多进程队列很慢。只是为了测试。
import socket
import json
import queue
import threading
import sys
#f = find lobby
pygame.init()
class Connection():
def __init__(self):
self.msgFromClient = "f"
self.bytesToSend = str.encode(self.msgFromClient)
self.serverAddressPort = ("", 10001)
self.bufferSize = 10000
self.sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
self.sock.setblocking(0)
self.sock.sendto(self.bytesToSend, self.serverAddressPort)
self.msgFromServer = self.sock.recvfrom(self.bufferSize)
self.msg = self.msgFromServer[0]
self.port = self.msg.decode("utf-8")
self.port = int(self.port)
self.serverAddressPort = ("", self.port)
self.q_listen = queue.Queue(1000)
self.q_send = queue.Queue(1000)
def listen(sock, buffer_size):
running = True
while running:
data_address = sock.recvfrom(buffer_size)
data = data_address[0].decode("utf-8")
data = json.loads(data)
self.q_listen.put(data)
def send(sock, serverAddressPort):
running = True
while running:
data = self.q_send.get()
if data:
data = json.dumps(data)
data = bytes(data, 'utf-8')
sock.sendto(data, serverAddressPort)
sock = self.sock
buffer_size = self.bufferSize
serverAddressPort = self.serverAddressPort
self.thread = threading.Thread(target = listen, args = (sock, buffer_size,))
self.thread2 = threading.Thread(target = send, args = (sock, serverAddressPort))
self.thread.daemon = True
self.thread2.daemon = True
self.thread.start()
self.thread2.start()
import global_variables as g
#de sters, o sa fie initializat in main game
g.screen = pygame.display.set_mode([1800, 900])
class Player(pygame.sprite.Sprite):
def __init__(self, color):
pygame.sprite.Sprite.__init__(self)
self.size = 60
self.image = pygame.Surface((self.size, self.size))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.center = (400, 400)
def Blit(self,screen):
screen.blit(self.image, self.rect)
class Test_Game():
def __init__(self):
g.variables_initialization()
self.surface_size = g.surface_size
self.surface = pygame.Surface((self.surface_size, self.surface_size))
self.surface_rect = self.surface.get_rect()
self.surface_rect.center = (800, 450)
self.running = True
self.player = Player(g.brown)
self.player2 = Player(g.green)
self.connection = Connection()
def Blit_Images(self):
g.screen.fill(g.white)
self.surface.fill(g.black)
self.player.Blit(self.surface)
self.player2.Blit(self.surface)
g.screen.blit(self.surface, self.surface_rect)
pygame.display.flip()
def Update(self):
dt = g.clock.tick(60) / 1000
pos = pygame.mouse.get_pos()
self.player.rect.centerx = pos[0] - 400
self.player.rect.centery = pos[1] - 50
coord = (self.player.rect.centerx, self.player.rect.centery)
self.connection.q_send.put(coord)
self.player2.rect.center = self.connection.q_listen.get()
def Check_Events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
def Loop(self):
while self.running == True:
self.Check_Events()
self.Update()
self.Blit_Images()
test_game = Test_Game()
test_game.Loop()
这里还有一个全局变量的文件(如果您想运行代码):https://pastebin.com/rhdwjekq
import pygame
def variables_initialization():
global clock
global dt
global screen
global surface_size
global white
global black
global green
global brown
global gray
clock = pygame.time.Clock()
dt = 0
surface_size = 800
white = (250, 250, 250)
black = (0, 0, 0)
green = (115, 198, 0)
brown = (102, 51, 0)
gray = (215, 218, 218)
这段代码的问题是,它会变得滞后,直到它完全冻结。一开始效果很好,但几秒钟后,方块看起来像是瞬移。我的猜测是可能是内存泄漏或我完全错误的东西,而不是真正的发送和接收的问题,因为我的方形也是滞后的,当程序冻结在那里,所以更多的打印从更新函数。一切都停止了。如果你知道为什么会这样,我会非常感激。我必须在本月30之前完成这个项目,我真的很迷茫,因为这个问题。任何建议都是很有帮助的!
我唯一能想到的就是两个while循环同时运行。检查您的线程并确保2个while循环不在同一线程上运行。
我试图建立一个通用服务器总是在连接的客户端。 该体系结构由4个主要组件组成 有状态应用服务器 无状态网关服务器 客户排队 系统和经纪人 工艺流程 客户端连接到网关 我正在使用JavaNetty作为网关。appserver也是用Java编写的。 我很想说这个设计像Mongrel2,但我不能完全确定。我想说,这更符合城市飞艇氦边缘服务器的设计(http://urbanairship.com/blog/
JAGS 游戏服务器是一个开源的 Java / AS 3.0 的游戏服务器,支持多玩家、碰撞检测以及键盘事件等等。
二本鼠鼠学Java没出路。。 技术面 - 50min - 9.26 自我介绍 介绍一下你的项目经历 MySQL索引底层结构 Redis有哪些数据结构 Redis的持久化机制 学过其他语言吗(c++和go),说一下c++、go、Java的区别 LRU怎么实现 最短路径算法实现 JVM垃圾回收算法 手撕在一排数据中算出不重复数据的子集 TCP三次握手 你知道什么是SYN攻击吗 TCP四次挥手为什么是四
过年回上海裸辞出去玩了一个月,5月回来找的工作,正好现在有时间了,抽空写一下社招面经,有些已经忘记了。裸辞还是太冲动了,菜鸡不配gap,两年工作经验不应该随便裸辞,还是太年轻、太狂妄了。当年校招腾讯、祖龙、小米等等offer随便拿,以为社招还跟校招一样简简单单,结果现在只能去个小公司养老了。 巨人网络(球球大作战) golang游戏后端,线下1、2、3面一起的 一面 项目架构图 pb的底层实现结构
最后,是否可以重复使用相同的runnable(每个游戏会话1个),而不是每回合创建一个新的。
我试图建立一个通用服务器总是在连接的客户端。 该体系结构由4个主要组件组成 有状态应用程序服务器 工艺流程 客户端连接到网关 我正在使用JavaNetty作为网关。appserver也是用Java编写的。 我很想说这个设计像Mongrel2,但我不能完全确定。我想说,这更符合城市飞艇氦边缘服务器的设计(http://urbanairship.com/blog/2010/08/24/c500k-in