好的,所以我正在使用python学习套接字编程。我将在适当的时候继续使用c。
我以为我会写一个愚蠢的游戏来学习套接字;请随意使用源代码(.bmp文件是我在gimp中制作的50x50像素图像)。服务器此时无法正常工作。(我很确定它挂在“ c,addr = s.accept()”上)
我认为处理此问题的方法是使用两个线程。一个线程来处理通信服务器端。一个线程来处理游戏循环,服务器端也是如此。目标是能够同时在服务器和客户端上玩游戏。我读过“ twisted模块”可以处理多线程,我以前从未做过多线程,但是这样做绝对不容易。
其次,我要实现服务器与客户端之间的通信,以免造成网络过载,并且不会激怒我的ISP(对于经验不足的开发人员来说,是Internet服务提供商)。有没有一种方法可以测试网络并查看在服务器和客户端之间实际传递了多少信息?
目前,我仅在客户端和服务器之间传递少量信息(仅当玩家通过按下按钮与客户端或服务器交互时才传递信息)。我应该使用更智能的消息传递模型吗?
GameServer.py
import pygame, sys, os
from pygame.locals import *
import socket
s = socket.socket()
host = socket.gethostname()
port = 6000
s.bind(('0.0.0.0',port))
s.listen(5)
#while True:
# c, addr = s.accept()
# print 'Got connection from', addr
# c.send('Hi blork, I am not rational either, but this works. So I am happy!')
# c.close()
window = pygame.display.set_mode((640,50))
pygame.display.set_caption("My Trivial Network Game: Get to the right side of the screen!")
class Ship():
xvel = 0
yvel = 0
x = 0
y = 0
image = pygame.image.load('ship.bmp')
def physics(self):
self.x += self.xvel
self.y += self.yvel
return self
class Bolt():
xvel = 0
yvel = 0
x = 640
y = 0
image = pygame.image.load('bolt.bmp')
def physics (self):
self.x += self.xvel
self.y += self.yvel
return self
def input(events):
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
sys.exit()
# elif event.key == pygame.K_f:
# ship.xvel = 2
elif event.key == pygame.K_z:
bolt.xvel = -4
s.send('zap')
pygame.display.set_caption("Oh no! Jon's being a dork!!")
c.close()
if event.type == QUIT:
sys.exit(0)
#def MakeShip():
# pygame
ship = Ship()
bolt = Bolt()
box = pygame.Rect(0,0,640,50)
loopVal = 0
while True:
pygame.draw.rect(window,(0,0,0),box,0)
window.blit(ship.image, (ship.x,ship.y))
window.blit(bolt.image, (bolt.x,bolt.y))
if loopVal == 0:
loopVal += 1
c, addr = s.accept()
print "Now have connection from address: ", addr
input(pygame.event.get())
ship.physics()
bolt.physics()
pygame.display.update()
if (ship.x > 640):
pygame.display.set_caption("You win!")
GameClient.py
import pygame, sys, os
from pygame.locals import *
import socket
s = socket.socket()
host = socket.gethostname()
port = 6000
window = pygame.display.set_mode((640,50))
pygame.display.set_caption("My Small Network Game: Get to the right side of the screen!")
class Ship():
xvel = 0
yvel = 0
x = 0
y = 0
image = pygame.image.load('ship.bmp')
def physics(self):
self.x += self.xvel
self.y += self.yvel
return self
class Bolt():
xvel = 0
yvel = 0
x = 640
y = 0
image = pygame.image.load('bolt.bmp')
def physics (self):
self.x += self.xvel
self.y += self.yvel
return self
def input(events):
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
sys.exit()
elif event.key == pygame.K_f:
ship.xvel = 2
# elif event.key == pygame.K_z:
# bolt.xvel = -4
# pygame.display.set_caption("Oh no! Jon's being a dork!!")
if event.type == QUIT:
sys.exit(0)
#def MakeShip():
# pygame
ship = Ship()
bolt = Bolt()
box = pygame.Rect(0,0,640,50)
s.connect((host, port))
reply = s.recv(1024)
print reply
while True:
pygame.draw.rect(window,(0,0,0),box,0)
window.blit(ship.image, (ship.x,ship.y))
window.blit(bolt.image, (bolt.x,bolt.y))
input(pygame.event.get())
ship.physics()
bolt.physics()
#reply = s.recv(1024)
print "He replied with zap!"
if reply == 'zap':
bolt.xvel = -4
pygame.display.set_caption("Oh no! Jon's being a dork!!")
pygame.display.update()
if (ship.x > 640):
pygame.display.set_caption("You win!")
您是正确的:s.accept()
阻塞直到建立连接。标准方法是使用线程。这是最简单的用法:
from threading import Thread
def server():
while True:
c, addr = s.accept()
print 'Got connection from', addr
c.send('Hi blork...')
c.close()
t = Thread(target=server)
t.start()
但是请注意,建立连接后,您应该侦听来自该套接字的传入数据。一种想法是为每个连接创建一个单独的线程:
from threading import Thread
from socket import SHUT_RDWR
def client(sock):
while True:
data = sock.recv(2048)
if not data:
break
print data
try:
sock.shutdown(SHUT_RDWR)
sock.close()
except:
pass
def server():
while True:
c, addr = s.accept()
print 'Got connection from', addr
c.send('Hi blork...')
t = Thread(target=client, args=(c,))
t.start()
t = Thread(target=server)
t.start()
如果您正在谈论一个游戏(一次最多只能有20个打开的连接),这应该足够有效。您不必费心诸如Twisted之类的复杂东西(通常应该用作高流量服务器)。
至于ISP:您根本不必担心。测试带宽的一种方法是再创建一个线程来ping客户端(例如每秒一次),然后客户端将向服务器发送信息。然后,您只需测量时间差即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句