我想用多人游戏编写一个问答游戏。 服务器部分选择问题,然后将其发送给客户端。客户端应答并将此答案发送到服务器。然后服务器检查它是否正确。我想循环这样做。 但问题是,存在时间问题,有时我的客户在能够回答之前没有收到问题。 另一个问题是,当客户端发送它时,服务器没有收到答案,我真的不知道原因。
这是我第一次进行网络编程,而且我很难理解线程和所有这些。 谢谢你的帮助=)
PS:这与另一个问题有关,我希望这段代码可以使用简单的图形界面......但这是下一步;)
这是我的客户代码:
import socket
import threading
import time
tLock = threading.Lock()
shutdown = False
def receving(name, sock):
while not shutdown:
try:
tLock.acquire()
while True:
data,addr = sock.recvfrom(1024)
print(str(data))
except:
pass
finally:
tLock.release()
#host = '192.168.26.86'
host = '127.0.0.1'
port = 0 #pick any free port currently on the computer
server = (host, 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
s.setblocking(0)
#receiving thread
rT = threading.Thread(target=receving, args=("RecvThread", s))
rT.start()
alias = raw_input("Name: ")
#PLAYER ENTERS DATA
message = raw_input(alias + "First msg ->")
while message != 'q':
tLock.acquire()
message = raw_input(alias + "What is your answer ? ->")
tLock.release()
if message != '':
s.sendto(alias + ": " + message, server)
time.sleep(0.2)
shutdown = True
rT.join()
s.close()
这是我的服务器代码:
import numpy as np
from numpy.random import shuffle
from random import randint
import socket
import time
#LIST OF QUESTIONS AND ANSWERS
question2 = ["What is the capital of France?","In which continent is Argentina?","Where is Big Ben?","What is the most densely populated country?","What language do they speak in Brazil?"]
answer2 = [["Paris","London","Berlin","Madrid"],
["South America","Africa","Europe","Asia"],
["London","New York","Mexico","Jakarta"],
["China","India","USA","Indonesia"],
["Portuguese","Spanish","French","English"]]
question_done=[0]*(len(question2))
#SCORE, stored as a list score[0]--> score of the player 1
score=[0]
#SHOW THE POSSIBLE ANSWERS
def displayA(question,answer,i):
a = answer[i]
order = np.arange(4)
shuffle(order) #create list from 1 to 4 in different order --> to print the answers in random order
a_display = [[a[order[0]],a[order[1]]],[a[order[2]],a[order[3]]]]
print(a_display)
#CHOOSE RANDOMLY A QUESTION IN THE LIST
def chooseQuestion(question,answer):
k = randint(0,len(question)-1)
if (question_done[k]!=0):
while(question_done[k]!=0):
k = randint(0,len(question)-1)
question_done[k]=1
else :
question_done[k]=1
print(question[k])
#displayA(question,answer,k)
return k
#CHECK IF GOOD ANSWER OR NOT
def checkAnswer(answer,agiven,qnb):
print("CHECK")
test = False
if(answer[qnb][0] in agiven):
test = True
score[0]=score[0]+1
print("ANSWER")
return test
#END OF GAME, DISPLAY OF SCORES
def final_score(score):
print("The scores are {}".format(score))
maxi = max(score)
if(score.count(maxi)==1):
print("The winner is Player {}".format(score.index(max(score))+1))
else :
winners = []
for i in range(len(score)):
if(score[i]==maxi):
winners.append(i+1)
print("The winners are players {}".format(winners))
"""
#Number of choosen questions, random order : GIVE THE QUESTION TO THE PLAYER
nb = 3
for k in range(nb):
nbq = chooseQuestion(question2,answer2)
agiven = raw_input("What is your answer? ")
result = checkAnswer(answer2,agiven,nbq)
print("Your answer is {}".format(result))
#Say who the winner is
final_score(score)
"""
#START THE NETWORK CODE
#host = '192.168.26.86'
host = '127.0.0.1'
port = 5000
#list for all the players
players = []
#creation of socket object UDP and bind
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
#socket non blocking --> will always try to grab datas from the stream
#not block it
s.setblocking(0)
quitting = False
print "Server Started."
#NUMBER OF QUESTIONS
nb = 3
while (not quitting and nb>0):
try:
data, addr = s.recvfrom(1024)
print("FIRST RECV {}".format(data))
if "Quit" in str(data):
quitting = True
if addr not in players:
players.append(addr)
print("liste players {}".format(players))
s.sendto("the game is starting ",players[len(players)-1])
print time.ctime(time.time()) + ":" + str(data)
#GAME
#for k in range(nb):
print("question nb {}".format(nb))
nbq = chooseQuestion(question2,answer2)
for i in range(len(players)):
print("ENTER FOR")
#s.sendto(question2[nbq], players[i])
try:
s.sendto(question2[nbq], players[i])
print("BEFORE GET ANSWER")
agiven, addr = s.recvfrom(1024)
print("GOT ANSWER")
print("agiven is : {}".format(agiven))
checkAnswer(answer2,agiven,nbq)
if "Quit" in str(agiven):
quitting = True
if addr not in players:
s.sendto("You cannot enter the game now ",addr)
else:
players[i] = addr
except:
pass
nb=nb-1
except:
pass
for i in range(len(players)):
try:
s.sendto("The game is finished, write q to quit",players[i])
except:
pass
final_score(score)
s.close()
答案 0 :(得分:0)
您的代码包含正确的问题和答案逻辑,但客户端和服务器之间的数据传输非常脆弱,只有在时机完美时才能正常工作。
我修改了你的代码以帮助控制时间,并阻止事情失序。我使用select()系统调用来处理超时,在客户端我更改了读取线程,以便在问题从服务器到达时通知主循环。
这段代码距离完美还有很长的路要走但它确实有用,它应该可以帮助你构建一些按照你喜欢的方式工作的最终代码。
注意我删除了"你现在无法加入游戏"代码,以帮助我调试原始代码,所以你可能现在可以把它。希望这有用。
客户代码:
import socket
import threading
import time
tEv = threading.Event()
tShutdown = threading.Event()
def receving(name, sock):
shutdown = False
while not shutdown:
try:
data,addr = sock.recvfrom(1024)
print(str(data))
if '?' in data:
tEv.set()
if data == "The game is finished": # message from server to stop
tShutdown.set()
shutdown = True
except:
pass
finally:
pass
#host = '192.168.26.86'
host = '127.0.0.1'
port = 0 #pick any free port currently on the computer
server = (host, 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
s.setblocking(0)
# Start listener
rT = threading.Thread(target=receving, args=("RecvThread", s))
rT.start()
# Join the game
alias = raw_input("Name: ")
s.sendto(alias, server)
running = True
while running:
if tEv.wait(1.0):
tEv.clear()
message = raw_input(alias + ", what is your answer ? -> ")
if message != '':
s.sendto(alias + ": " + message, server)
if tShutdown.is_set():
running = False
rT.join()
s.close()
服务器代码:
import numpy as np
from numpy.random import shuffle
from random import randint
import socket
import time
import select
#LIST OF QUESTIONS AND ANSWERS
question2 = ["What is the capital of France?","In which continent is Argentina?","Where is Big Ben?","What is the most densely populated country?","What language do they speak in Brazil?"]
answer2 = [["Paris","London","Berlin","Madrid"],
["South America","Africa","Europe","Asia"],
["London","New York","Mexico","Jakarta"],
["China","India","USA","Indonesia"],
["Portuguese","Spanish","French","English"]]
question_done=[0]*(len(question2))
#SCORE, stored as a list score[0]--> score of the player 1
score=[0]
#SHOW THE POSSIBLE ANSWERS
def displayA(question,answer,i):
a = answer[i]
order = np.arange(4)
shuffle(order) #create list from 1 to 4 in different order --> to print the answers in random order
a_display = [[a[order[0]],a[order[1]]],[a[order[2]],a[order[3]]]]
print(a_display)
#CHOOSE RANDOMLY A QUESTION IN THE LIST
def chooseQuestion(question,answer):
k = randint(0,len(question)-1)
if (question_done[k]!=0):
while(question_done[k]!=0):
k = randint(0,len(question)-1)
question_done[k]=1
else :
question_done[k]=1
print(question[k])
#displayA(question,answer,k)
return k
#CHECK IF GOOD ANSWER OR NOT
def checkAnswer(answer,agiven,qnb):
#print("CHECK")
test = False
if(answer[qnb][0] in agiven):
test = True
score[0]=score[0]+1
#print("ANSWER")
return test
#END OF GAME, DISPLAY OF SCORES
def final_score(score):
print("The scores are {}".format(score))
maxi = max(score)
if(score.count(maxi)==1):
print("The winner is Player {}".format(score.index(max(score))+1))
else :
winners = []
for i in range(len(score)):
if(score[i]==maxi):
winners.append(i+1)
print("The winners are players {}".format(winners))
"""
#Number of choosen questions, random order : GIVE THE QUESTION TO THE PLAYER
nb = 3
for k in range(nb):
nbq = chooseQuestion(question2,answer2)
agiven = raw_input("What is your answer? ")
result = checkAnswer(answer2,agiven,nbq)
print("Your answer is {}".format(result))
#Say who the winner is
final_score(score)
"""
#START THE NETWORK CODE
#host = '192.168.26.86'
host = '127.0.0.1'
port = 5000
#list for all the players
players = []
#creation of socket object UDP and bind
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
#socket non blocking --> will always try to grab datas from the stream
#not block it
s.setblocking(0)
print "Server Started."
#INITIAL SETUP PERIOD
secs = 20
max_players = 5
# WAIT FOR PLAYERS TO JOIN
while ((secs > 0) and (len(players) < max_players)):
ready = select.select([s], [], [], 1)
if ready[0]:
data, addr = s.recvfrom(1024)
print("FIRST RECV {}".format(data))
if addr not in players:
players.append(addr)
print("liste players {}".format(players))
s.sendto("Wait for game to start... ",players[len(players)-1])
print time.ctime(time.time()) + ":" + str(data)
secs = secs - 1
#START GAME
print("Game starting")
for i in range(len(players)):
try:
s.sendto("Game starting", players[i])
except:
pass
#ASK QUESTIONS
nb = 3
for k in range(nb):
print("question nb {}".format(k))
nbq = chooseQuestion(question2,answer2)
#print("ENTER FOR")
for i in range(len(players)):
try:
s.sendto(str(question2[nbq]), players[i])
#print("BEFORE GET ANSWER")
agiven = ""
ready = select.select([s], [], [], 10)
if ready[0]:
agiven, addr = s.recvfrom(1024)
#print("GOT ANSWER")
print("agiven is : {}".format(agiven))
checkAnswer(answer2,agiven,nbq)
except:
pass
for i in range(len(players)):
try:
s.sendto("The game is finished", players[i])
except:
pass
final_score(score)
s.close()