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.clientSockNone调用self.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 回答