0

私は本当に短くて簡単な質問があります:

別の python ファイル/クラスから send() メソッドを呼び出す方法は? 別のコンポーネントからクライアントにメッセージを送信したい (接続が確立されている)。

シングルトンインスタンスの参照を取得してから、次のように「送信」するだけでよいと思いました。

server = Server(ip,port)
server.send("hello")

そのようにすると、エラーが発生します。

NoneType' object has no attribute 'send'

ここで問題になるのは「自分」かもしれません...

サーバークラスは次のとおりです。

class Server(threading.Thread):

    ##############################################################################
    # Server: Singleton Instance
    ##############################################################################
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Server, cls).__new__(cls, *args, **kwargs)
        return cls._instance    

    ##############################################################################
    # Constructor of Server
    ##############################################################################
    def __init__(self, host, port):
        threading.Thread.__init__(self)
        print "[SERVER____] Creating Server Thread"
        self.host = host
        self.port = port
        self.__reset__()  

    ##############################################################################
    # Resetting local attributes
    ##############################################################################
    def __reset__(self):   
        print "[SERVER____] Reset"         
        self.serverSock = None
        self.clientSock = None
        self.clientAddr = None
        self.clientData = None
        self.isRunning = None
        self.isWaiting = None

    ###########################################################################                
    def send(self, message):
        print "[SERVER____] Sending Message", message
        self.clientSock.send(message)

    ##############################################################################
    # Stop the Server: Close the Socket and Reset
    ##############################################################################
    def stop(self):            
        # Close The Client Socket
        if(self.clientSock): 
            self.clientSock.close()
            print "[SERVER____] Aborting Client Socket"
        # Close The Server Socket    
        if(self.serverSock): 
            self.serverSock.close()
            print "[SERVER____] Aborting Server Socket"
        # Reset the Member Fields
        self.__reset__()
        print "[SERVER____] Aborting Server Thread"
        self._Thread__stop()

    ##############################################################################
    # Server.start()
    ##############################################################################
    def run(self):          
        try:
            # Create The Socket
            self.serverSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            print "[SERVER____] Creating Server Socket"
            # Set Socket Options
            #self.serverSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
            # Bind The New Socket
            self.serverSock.bind((self.host, self.port))
            print "[SERVER____] Binding Server Socket"
            print "[SERVER____] IP: ", self.host, " Port: ", self.port
            # Set The Awaiting Flag
            self.isWaiting = True;
            # Start The Server Loop
            while self.isWaiting:
                # Listen On New Socket
                self.serverSock.listen(1)
                print "[SERVER____] Listening Server Socket"
                # Accept New Connection            
                self.clientSock, self.clientAddr = self.serverSock.accept()     
                print "[SERVER____] Accepting New Connection: " , self.clientAddr
                # Set The Running Flag
                self.isRunning = True;     
                # Serve The Connection
                while self.isRunning:
                    print "[SERVER____] Want to recv message...."
                    try:
                        # Receive A New Data Block    
                        self.clientData = self.clientSock.recv(config.BUFFERSIZE)
                        # Process The New Data Block
                        if not self.clientData:                       
                            print "[SERVER____] Reset By Client Connection"
                            break
                        else:    
                            print "[SERVER____] Receiving Message: ", self.clientData
                            parser = MessageParser()
                            parser.parseSMMessage(self.clientData)                    
                    except socket.error:
                        print "[SERVER_ERR] Error at receiving data from client."                            
        except Exception as exc:
            print "[SERVER____] Server Thread Exception ", exc
4

1 に答える 1

1

シングルトン パターンの実装が間違っているため、 を呼び出す前self.clientSockに が設定されます。シングルトンインスタンスを取得するたびに呼び出すため、実装が間違っています。基本的に、何が起こるか:Noneself.clientSock.send__init__

  1. Server(...)インスタンスを取得するために呼び出します。
  2. runそのインスタンスで呼び出されます。これにより、 が設定されますself.clientSock
  3. Server(...)インスタンスを再度取得するために呼び出します。の実装により、これは同じインスタンスを返しますが__new____init__再度呼び出されて にself.clientSockリセットされNoneます。
  4. を呼び出すself.clientSock.sendと、例外が発生します。

シングルトンが必要な場合は、使用してシングルトンを実装しないことをお勧めし__new__ます (ただし、シングルトンをまったく使用しないことがおそらく最善です)。他のいくつかの方法をここにリストします。

于 2013-08-08T15:28:36.177 に答える