2015-10-01 2 views
0

Я написал сценарий в игре блендера, и я использую сокеты, у меня есть Server.blend и client.blend.Закрытие сокета при завершении игры

это конструктор моего сервера:

class Server: 

def __init__(self, host="127.0.0.1", port= 9238): 

    self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    self.socket.setblocking(False) 
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    self.socket.bind((host, port)) 

и это мой клиент:

class Client: 

def __init__(self, server_ip="127.0.0.1", server_port= 9238): 

    self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    self.socket.setblocking(False) 

    self.serv_addr = (server_ip, server_port) 

Проблема заключается в том, что я не знаю, когда клиент собирается выйти из игры, так Я не могу закрыть его сокет, что поддерживает открытый порт, поэтому я не могу использовать текущий порт снова.

У меня есть словарь, который содержит все адреса всех клиентов, поэтому я попытался отправить сообщение всем адресам, и в случае отсоединения клиента я не смогу отправить сообщение и использовать и исключение для удаления адреса из списка (и это аватар и т.д ..):

def Check_For_Disconnect(self): 
    for addr in self.addr_user: 
     try: 
      self.socket.sendto(b"You are connected!" , addr) 
     except socket.error: 
      scene = logic.getCurrentScene() 
      for obj in scene.objects: 
       if str(obj) == "Text" and obj == self.addr_user[addr].name: 
        obj.delete() 
        del self.addr_user[addr] 

Я полагаю, что я не дотягиваю исключение, потому что сокет клиента остается открытым, так что сообщение поступает правильно.

Есть ли у кого-нибудь идеи, как я могу обойти эту проблему?

+0

просьба сообщить код - как отслеживать действия пользователей и т.д., если вы не отслеживать его/ее деятельности, это очень трудно получить информацию, когда он/она покидает игру. – marmeladze

+0

Не уверен, в чем вопрос. Когда клиент отключается, сообщается событие disconnet (я принимаю TCP). – SergeyA

+0

В этом проблема. Я не использую TCP, я отредактировал свой вопрос и добавил код, так что теперь вы можете видеть, что я его не использую. – Maor2871

ответ

0

Клиент должен отправить информацию о выходе из игры, поэтому сервер точно знает, когда закрыть сокет. Таким образом, процесс инициируется клиентской стороной.

+0

Итак, совет вы должны отправить сообщение клиент, который спрашивает его, действительно ли он хочет уйти? и тогда я смогу узнать, что он уходит? это хорошая идея, но у меня все еще есть проблема, что в блендере клиент может нажать esc всякий раз, когда захочет, и закрыть игру. Тогда я не знаю, что он ушел. – Maor2871

+0

Вам не нужно спрашивать клиента. Если он остановит процесс, он отправит сигнал на сервер. Клиентская программа не позволяет выйти из программы, пока не будет отправлено автоматическое сообщение о выходе. –

+0

, но клиент не закрыл сокет, порт все еще открыт, и он все еще может получать сообщения, он не может их показать, потому что нет кода, который может это сделать. Прежде чем клиент остановит процесс, он должен закрыть его. Я полагаю, что сигнал отправляется, когда клиент останавливает сокет. – Maor2871

0

Я нашел решение: я не знаю, когда клиент собирается выйти из игры, поэтому я не могу закрыть его сокет, я знаю, что только когда клиент запускает свою игру - он может отправить сообщений на сервер. поэтому, пока сервер в эфире, он запрашивает у клиента «подключенное» сообщение. Каждый раз, когда сервер не получает сообщение от клиента, он считает это. Теперь вам решать, сколько нужно делать, пока вы не убедитесь, что клиент отключен.

Это мой метод получить:

def receive(self): 

    while True: 
     for k in self.addr_connected: 
      if self.addr_connected[k] > 50: 
       self.Remove_Client(k) 
       break 

     try: 

      data, addr = self.socket.recvfrom(1024) 

      if not addr in self.addr_user: 

       user= User(data.decode()) 

       scene = logic.getCurrentScene() 
       spawner = scene.objects['Spawner'] 
       avatar = scene.addObject("Avatar", spawner) 
       avatar.children[0]['Text'] = user.name 
       avatar['user']= user 

       self.addr_user[addr] = user 
       self.addr_connected[addr] = 0 

      else: 
       user= self.addr_user[addr] 
       try: 
        user.keyboard.updateState(pickle.loads(data)) 
       except: 
        data = data.decode() 
        if data == "I am connected": 
         self.addr_connected[addr] = 0 
         for k in self.addr_connected: 
          if k != addr: 
           self.addr_connected[k] += 1 

     except socket.error: 
      for k in self.addr_connected: 
       self.addr_connected[k] += 1  
      break 

 Смежные вопросы

  • Нет связанных вопросов^_^