[英]Client disconnects when another client connects to the server
我正在用 Python 編寫一個加密的 RPS(石頭、紙、剪刀)游戲,它的工作原理是這樣的。 服務器主導游戲,兩個客戶端只是將他們的選擇發送到服務器。
首先,服務器正在等待 2 名玩家加入,當 2 名玩家加入時,他正在開始游戲並讓兩個客戶端選擇一個選項。
我的問題是,當第一個客戶端連接時,然后另一個客戶端會自動斷開連接。 所以,我不知道如何處理兩個客戶,讓第一個客戶選擇一個選項,然后讓第二個客戶選擇一個選項。
*注意:我為兩個客戶端使用相同的客戶端文件。
服務器:
import socket
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from time import sleep
def rules(first_choice, second_choice, mem1, mem2) -> str:
if (first_choice == 'R' and second_choice == 'P'
or first_choice == 'P' and second_choice == 'S'
or first_choice == 'S' and second_choice == 'R'):
return f'Result: Player 2 Won\nPlayer 1 Choice - {first_choice}\nPlayer 2 Choice - {second_choice}'
else:
return f'Result: Player 1 Won!\nPlayer 1 Choice - {first_choice}\nPlayer 2 Choice - {second_choice}'
class Connect:
def __init__(self):
players = 0
self.prikey = RSA.generate(1024)
self.pubkey = self.prikey.publickey()
self.token = PKCS1_OAEP.new(self.prikey)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind(('0.0.0.0', 21523))
sock.listen(2)
print('Waiting for at least 2 players, please wait.')
while True:
self.conn, self.addr = sock.accept()
players += 1
if players == 1:
print(f'Player 1 is {self.addr}')
self.player1 = self.addr
elif players == 2:
print(f'Player 2 is {self.addr}')
self.player2 = self.addr
self.connection()
def connection(self) -> None:
print('2 Players have joined, starting game in 5 seconds.\n')
sleep(5)
self.conn.send('Y'.encode())
self.game_play()
def game_play(self) -> None:
self.conn.send(self.pubkey.exportKey())
choice_1_cipher = self.conn.recv(1024)
choice_1_plain = self.token.decrypt(choice_1_cipher)
print('Got first choice, waiting for another choice..')
choice_2_cipher = self.conn.recv(1024)
choice_2_plain = self.token.decrypt(choice_2_cipher)
print('Got second answer, calculating winner!')
print(rules(choice_1_plain, choice_2_plain, self.player1, self.player2))
if __name__ == '__main__':
Connect()
客戶:
import socket
import random
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
class Client:
def __init__(self):
self.prikey = RSA.generate(2048)
self.pubkey = self.prikey.publickey()
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect(('10.0.0.42', 21523))
data = self.sock.recv(1024).decode()
if data == 'Y':
self.start_game()
def start_game(self) -> None:
print('\n [R]ock | [P]aper | [S]cissors - ')
while True:
my_choice = input().upper()
if my_choice not in ['R', 'P', 'S']:
print('Invalid Input, input must be one of those R\\P\\S')
else:
user_pubkey = RSA.importKey(self.sock.recv(2048))
token = PKCS1_OAEP.new(user_pubkey)
cipher_choice = token.encrypt(my_choice.encode())
self.sock.send(cipher_choice)
if __name__ == '__main__':
try:
Client()
except Exception as e:
print(f'err: {e}')
except KeyboardInterrupt:
print('A player has pressed [Ctrl + C] to quit the game, game ended!')
self.conn
中的self.conn, self.addr = sock.accept()
當 2 個客戶端連接時被覆蓋,並且 player1 的 self.conn 丟失。 我想您應該將 self.conn 分配給self.player1_conn
,然后返回到等待 2 玩家的 while 循環的開頭。
這實際上是您的腳本中經常出現的問題,因為當您說self.conn.send('Y'.encode())
self.conn
僅指第二個播放器連接(我想這不是您打算做的) .
您應該將player1_conn
和player2_conn
中的 conn 分開,然后您就可以選擇向哪個玩家發送您需要的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.