#python #sockets
Вопрос:
В настоящее время я работаю над простым школьным проектом на игровом сервере. У меня есть одна концептуальная проблема для работы с измененными данными в TCPServer.
Я создал простую программу для решения этих проблем. Клиенты сначала наберут номер, и номер будет отправлен на сервер. Этот номер будет обработан на сервере путем добавления 1, и сервер отправит измененный номер обратно клиентам. Кроме того, измененный номер также будет сохранен в том totalNum
, в котором хранится вся сумма измененного номера клиентов.
Я ожидаю, что сервер будет «хранить» номер клиента. Например, когда клиент A отправит номер 5, totalNum
будет 6. После этого, когда клиент B отправит номер 8, данные клиента A все равно должны сохраняться в сервере, я ожидаю totalNum
, что будет 6 9 = 15.
Server.py
#!/usr/bin/python3 import socket import threading class ServerThread(threading.Thread): def __init__(self, client): threading.Thread.__init__(self) self.client = client def run(self): connectionSocket, addr = self.client totalNum = 0 number = connectionSocket.recv(1024) newNumber = number.decode() newNumber = int(newNumber) editedNumber = newNumber 1 #add the edited number to the totalNum in the server totalNum = editedNumber totalNum print (totalNum) #change back to str for sending editedNumber = str(editedNumber) connectionSocket.send(editedNumber.encode()) connectionSocket.close() class ServerMain: def server_run(self): serverPort = 12000 serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serverSocket.bind( ("", serverPort) ) serverSocket.listen(5) print("The server is ready to receive") while True: client = serverSocket.accept() t = ServerThread(client) t.start() if __name__ == '__main__': server = ServerMain() server.server_run()
Client.py
#!/usr/bin/python3 import socket clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serverName = "localhost" serverPort = 12000 clientSocket.connect( (serverName, serverPort) ) # Get input for sending number = input("Input a number:") clientSocket.send(number.encode()) modifiednumber = clientSocket.recv(1024) print("From Server:", modifiednumber.decode()) clientSocket.close()
updated server code(changing the totalNum
to class variable):
#!/usr/bin/python3 import socket import threading class ServerThread(threading.Thread): totalNum = 0 def __init__(self, client): threading.Thread.__init__(self) self.client = client def run(self): connectionSocket, addr = self.client number = connectionSocket.recv(1024) newNumber = number.decode() newNumber = int(newNumber) editedNumber = newNumber 1 #add the edited number to the totalNum in the server self.totalNum = editedNumber self.totalNum print (self.totalNum) #change back to str for sending editedNumber = str(editedNumber) connectionSocket.send(editedNumber.encode()) connectionSocket.close() class ServerMain: def server_run(self): serverPort = 12000 serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serverSocket.bind( ("", serverPort) ) serverSocket.listen(5) print("The server is ready to receive") while True: client = serverSocket.accept() t = ServerThread(client) t.start() if __name__ == '__main__': server = ServerMain() server.server_run()
Ответ №1:
Вы довольно близки. переместитесь totalNum = 0
в переменную уровня класса, т. е.
class ServerThread(threading.Thread): totalNum = 0 def __init__(self, client):
и где бы вы ни использовали totalNum
, используйте его как ServerThread.totalNum
Проблема заключалась в том, что у вас был totalNum в качестве переменной области видимости, поэтому он терялся каждый раз, когда вы заканчивали run()
. проблема возникает, если мы создали totalNum
переменную экземпляра. когда run()
заканчивается поток заканчивается, и значение снова теряется! сделав его переменной класса, он всегда будет там и всегда будет общим. вы также можете получить доступ к нему из-за пределов класса с помощью ServerThread.totalNum
Комментарии:
1. Те же проблемы все еще существуют. Я переместил переменную
totalNum
на уровень класса. Сначала я запускаю серверную программу, а также запускаю две клиентские программы и набираю номер. ПервыйtotalNum
номер клиента не был добавлен. Я считаю, что ваш подход верен, и я предполагаю, что, возможно, я сделал что-то не так, когда тестировал программу.2. @Dario пожалуйста, обновите вопрос новым кодом сервера (просто добавьте его в конец)
3. Обновленный код прилагается в конце. В моей программе я хотел бы спросить, когда каждый клиент завершает свое TCP-соединение с сервером, данные сервера должны, как предполагается, содержать последние обновленные данные?
4. @Dario я случайно написал
self
вместоServerThread
этого . я обновил ответ, который вы хотите использоватьServerThread.totalNum
для доступа вместоself.totalNum
. Что касается вашего вопроса, да, сервер будет поддерживать номер.