My target is print the message from function result
on the client's screen. But only ONE client can received the message...
The part of client.py is here
def PlayGame(clientSocket, msg):
invalid = "NO!"
if ("/guess " in msg):
msg1 = msg.split(" ")[1]
print("Hi1\n")
if msg1 == "true" or msg1 == "false":
print("Hi11")
clientSocket.send(msg1.encode())
print(clientSocket.recv(1024).decode())
print("!")
return '1'
else:
clientSocket.send(invalid.encode())
print(clientSocket.recv(1024).decode())
print("2")
return '2'
elif msg == "":
return '2'
else:
clientSocket.send(invalid.encode())
print(clientSocket.recv(1024).decode())
print("3")
return '2'
def main(argv):
msg=""
while (PlayGame(clientSocket, msg)!=1):
msg = input()
Any part of the server.py
guess_box = []
guess = bool(random.randint(0, 1))
def result(connectionSocket, guess_box, addr, addr_l):
a = 0
if(guess_box[0] == guess_box[1]):
msg = "Tie!!"
connectionSocket.send(msg.encode())
return '2'
elif(guess_box[0] == guess):
msg = "Player 1 Wins!"
a =1
connectionSocket.send(msg.encode())
return '2'
elif(guess_box[1] == guess):
msg = "Player 2 Wins!"
a =1
connectionSocket.send(msg.encode())
return '2'
def TF(connectionSocket, var, guess_box, addr, addr_l):
msg = connectionSocket.recv(1024).decode()
print("recv:",msg)
if(msg == 'true'):
msg = 'True'
var = str(var)
msg = bool(msg == var)
guess_box.append(msg)
return 'ok'
elif(msg == 'false'):
msg = 'False'
var = str(var)
msg = bool(msg == var)
guess_box.append(msg)
return 'ok'
else:
print(msg)
statement = "4002 Unrecognized message!!"
connectionSocket.send(statement.encode())
return 'again'
class ServerThread(threading.Thread):
def __init__(self, client):
threading.Thread.__init__(self)
self.client = client
def run(self):
...
print("guess is:", guess)
while (len(guess_box) != 2):
TF(connectionSocket, guess, guess_box, addr, addr_l)
print("start")
result(connectionSocket, guess_box, addr, addr_l)
...
CodePudding user response:
Regarding only the one problem you address:
print the message from function result on the client's screen. But only ONE client can received the message
The problem comes from the use of a different thread for each client. The thread which receives a guess as first stays in its
while (len(guess_box) != 2):
print(guess_box)
TF(connectionSocket, guess, guess_box)
loop and waits for another message, which doesn't come. The thread which receives a guess as second sends the result to its own client only.
I don't think there's a sensible way to fix this while keeping this dthreaded approach.
Can I change the structure of my code by using those functions I implemented?
Here's a substitute for the while True
loop in server_run
that doesn't require changes in those functions other than server_run
.
from select import select
connections = []
room_connection = {}
for reads in iter(lambda: select([serverSocket] connections, [], [])[0], []):
for ready in reads: # for each socket which select reports is readable
if ready == serverSocket: # it's the server socket, accept new client
connectionSocket, addr = serverSocket.accept()
connections.append(connectionSocket)# store the connection socket
while RecvFromClient(connectionSocket) == "NO": pass
else: # message (or disconnect) from a client
try: var = GameHallMsg(ready, ready, connections)
except socket.error: var = 'bye'
if var == 'bye': # client finished, remove from list
connections.remove(ready)
ready.close()
elif var == 'wait': # store first player's connection
room_connection[current_rm_num.pop()] = ready
elif var == 'NO':
rtn_msg_4 = "4002 Unrecognized message"
ready.send(rtn_msg_4.encode())
elif var == 'jump':
readyroom = current_rm_num.pop()
# find and notify other player in the room
other = room_connection.pop(readyroom)
rtn_msg_2 = "3012 Game started. Please guess true or false"
other.send(rtn_msg_2.encode())
print("guess is:", guess)
# query and inform both players
guess_box = []
while TF(ready, True, guess_box) != 'ok': pass
while TF(other, True, guess_box) != 'ok': pass
result(ready, guess_box, ('', 0), [0])
result(other, guess_box, ('', 1), [0, 1])
room[readyroom] = 0