Сбой сервера программирования сокетов Python и нескольких клиентов при хранении данных

#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 . Что касается вашего вопроса, да, сервер будет поддерживать номер.