Я довольно новичок в программировании на python.Я пытаюсь кодировать какую-то форму симуляции, используя сокеты.Я могу успешно подключить несколько клиентов к серверу.Однако я хотел бы, чтобы сервер принимал клиентские соединения, ожидая некоторого ввода (скажем, клавиши ввода или ввода строки из консоли / терминала).Если пользователь нажимает клавишу ввода или вводит эту строку, то сервер должен прекратить принимать клиентские соединения и отправить список подключенных клиентов всем клиентам.Я знаю, как кодировать оставшуюся часть, но я не знаю, где обнаружить нажатие этой клавиши при принятии соединений.Это то, что я до сих пор.Я пытался найти похожие подходы, но не нашел того, что соответствует моим потребностям.
Файл сервера:
import socket, sys, traceback, json, pygame, curses, time
from threading import Thread
clientList = {}
def initialize():
serverConnect()
def serverConnect():
local_hostname = socket.gethostname()
host = socket.gethostbyname(local_hostname)
port = 6666
sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockfd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sockfd.bind((host, port))
except:
print("Bind failed. Error : " + str(sys.exc_info()))
sys.exit()
sockfd.listen(3)
cid = 0
# infinite loop - do not reset for every requests
while True:
print("Awaiting client connection...")
clientSocket, address = sockfd.accept()
cid += 1
add_client_to_list(cid, address)
ip = str(address[0])
port = str(address[1])
print("Connected with " + ip + ":" + port)
try:
Thread(target=client_thread, args=(clientSocket, ip, port, cid, address)).start()
except:
print("Thread did not start.")
traceback.print_exc()
sockfd.close()
def client_thread(clientSocket, ip, port, cid, address, BUFSIZE = 5120):
clientAddress = address
clientID = cid
print("Sending client ID " + str(clientID) + " to " + ip + ":" + port)
clientSocket.sendall(str(clientID).encode("utf-8"))
threadActive = True
while threadActive:
recdData = receive_input(clientSocket, BUFSIZE)
if "--QUIT--" in recdData:
print("Client is requesting to quit")
clientSocket.close()
print("Connection " + ip + ":" + port + " closed")
threadActive = False
else:
print("\nReceived: {}".format(recdData) + " from %d" %clientID)
clientSocket.sendall("-".encode("utf8"))
def receive_input(clientSocket, BUFSIZE):
recdData = clientSocket.recv(BUFSIZE)
recdDataSize = sys.getsizeof(recdData)
if recdDataSize > BUFSIZE:
print("The input size is greater than expected {}".format(recdDataSize))
decodedData = recdData.decode("utf8").rstrip() # decode and strip end of line
result = process_input(decodedData)
return result
def process_input(input_str):
return str(input_str).upper()
def add_client_to_list(client_ID, client_address):
clientList[client_ID] = client_address
print(clientList)
def send_client_list(clientSocket, clientList):
jsonList = json.dumps(clientList)
clientSocket.sendall(str(jsonList).encode("utf-8"))
def keyPress(stdscr):
"""checking for keypress"""
stdscr.nodelay(True) # do not wait for input when calling getch
return stdscr.getch()
if __name__ == "__main__":
initialize()
Файл клиента:
import socket
import sys
import json
def initialize():
sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 6666
try:
sockfd.connect((host, port))
except:
print("Connection error")
sys.exit()
# Receiving server assigned client ID
try:
myID = sockfd.recv(1024).decode("utf-8")
print("Received ID: " + myID + " from server.")
except:
print("Could not receive my ID from server")
sys.exit()
print("Enter 'quit' to exit and 'list' to receive client List")
message = input(" -> ")
while True:
if message == "list":
print("Receiving clientList from server...")
try:
jsonList = sockfd.recv(8192).decode("utf-8")
clientList = json.loads(jsonList)
print("Received list: %s" % clientList)
except:
print("Could not receive list from server")
sys.exit()
elif message != 'quit':
sockfd.sendall(message.encode("utf8"))
if sockfd.recv(5120).decode("utf8") == "-":
pass
message = input(" -> ")
else:
sockfd.send(b'--quit--')
break;
if __name__ == "__main__":
initialize()
Это то, что я нашел.Это небольшой скрипт, который определяет, вводит ли пользователь {a} в консоль.И если он делает, то сообщение печатается.В противном случае он продолжает прослушивать нажатия клавиш.
import curses, time
def keyPress(stdscr):
# checking for keypress
stdscr.nodelay(True) # do not wait for input when calling getch
return stdscr.getch()
while True:
if curses.wrapper(keyPress) == 97:
print("You pressed 'a'")
else:
pass
time.sleep(0.1)
Было бы здорово, если бы вы могли подсказать мне, как я могу использовать эту концепцию для обнаружения нажатия клавиш на стороне сервера и прекращения приема клиентских подключений и вызова функции дляотправить список клиентов всем клиентам.Или если у вас есть другие подходы или предложения.