2009-04-02 5 views
2

Das ist ein Problem. Meine primäre Arbeit ist: Liefern "s" Objekt zu "Handle" -Methode in der TestRequestHandler-Klasse. Mein erster Schritt war: liefern "s" Objekt durch "Punkt" -Methode zu TestServer-Klasse, aber hier bin ich fest. Wie "s" Objekt zu TestRequestHandler zu liefern? Einige Vorschläge?Wie eine Instanz des Objekts an die Instanz von SocketServer.BaseRequestHandler übergeben wird?

import threading 
import SocketServer 
from socket import * 

class TestRequestHandler(SocketServer.BaseRequestHandler): 

    def __init__(self, request, client_address, server): 
     SocketServer.BaseRequestHandler.__init__(self, request, client_address, server) 
     return 

    def setup(self): 
     return SocketServer.BaseRequestHandler.setup(self) 

    def handle(self): 
     data = self.request.recv(1024) 

     if (data): 
      self.request.send(data) 
      print data 

    def finish(self): 
     return SocketServer.BaseRequestHandler.finish(self) 

class TestServer(SocketServer.TCPServer): 

    def __init__(self, server_address, handler_class=TestRequestHandler): 
     print "__init__" 
     SocketServer.TCPServer.__init__(self, server_address, handler_class) 
     return 

    def point(self,obj): 
     self.obj = obj 
     print "point" 

    def server_activate(self): 
     SocketServer.TCPServer.server_activate(self) 
     return 

    def serve_forever(self): 
     print "serve_forever" 
     while True: 
      self.handle_request() 
     return 

    def handle_request(self): 
     return SocketServer.TCPServer.handle_request(self) 

if __name__ == '__main__': 

    s = socket(AF_INET, SOCK_STREAM) 

    address = ('localhost', 6666) 
    server = TestServer(address, TestRequestHandler) 
    server.point(s) 
    t = threading.Thread(target=server.serve_forever()) 
    t.setDaemon(True) 
    t.start() 
+0

Ich bin verwirrt. Ihr Server öffnet einen Socket auf localhost: 6666. Was ist dieser andere Socket, den du erstellst und den du "zeigen" willst? Soll das ein Client-Socket zum Testen sein? –

+0

Ich bin auch ein wenig verwirrt. Mit "liefern" meinen Sie die Inter-Thread-Kommunikation? Oder versuchen Sie, einen Remote-Prozedur-Aufruf durchzuführen, indem Sie das Objekt über die Leitung an den Server senden? Ich gestehe, ich verstehe nicht, was du mit "Punkt" meinst. –

Antwort

1

Wenn der Wert von s einmal festgelegt ist, und nicht neu initialisiert - man könnte es eine Klassenvariable macht im Gegensatz zu einer Instanzvariablen von Testserver, und dann muss den Handler es über eine Klassenmethode von Testserver abrufen in der Konstruktor des Handlers.

zB: TestServer._mySocket = s

2

Wenn ich richtig verstehe, ich glaube, Sie vielleicht Missverständnisse sind, wie das Modul arbeitet. Sie geben bereits eine Adresse von "localhost: 6666" an, für die der Server binden soll.

Wenn Sie den Server über Ihren Aufruf von serve_forever() starten, wird der Server damit beginnen, einen Socket auf localhost zu hören: 6666.

Gemäß der Dokumentation wird dieser Socket als Request-Objekt an Ihren RequestHandler übergeben. Wenn Daten auf dem Socket empfangen werden, sollte Ihre Handle-Methode in der Lage sein, von/zu diesem Objekt über die dokumentierte Socket-API zu senden/zu senden.

Wenn Sie eine weitere Abstraktion wünschen, sieht es so aus, als könnte Ihr RequestHandler von StreamRequestHandler ausgehen und stattdessen mit dateiähnlichen Objekten in den Socket lesen/schreiben.

Der Punkt ist, müssen Sie keinen zusätzlichen Socket erstellen und dann versuchen, Ihren Server zu zwingen, stattdessen den neuen zu verwenden. Ein Teil des Werts des SocketServer-Moduls besteht darin, dass es den Lebenszyklus des Sockets für Sie verwaltet.

Auf der anderen Seite, wenn Sie Ihren Server aus der Perspektive eines Clients testen möchten, dann möchten Sie einen Socket erstellen, auf dem Sie Ihre Clientanforderungen lesen/schreiben können. Aber Sie würden diesen Socket niemals per se an Ihren Server weitergeben. Sie würden dies wahrscheinlich in einem völlig separaten Prozess tun und Ihren Server über IPC über den Socket testen.

Bearbeiten neue Informationen

Um Server A zu öffnen, ein Socket-Server B zu erhalten, wenn ein Server Daten eine Lösung erhält, ist einfach eine Steckdose öffnen aus Ihrem Request. Das heißt, es gibt wahrscheinlich einige andere Design-Bedenken, die Sie basierend auf den Anforderungen Ihres Dienstes ansprechen müssen.

Beispielsweise möchten Sie möglicherweise einen einfachen Verbindungspool verwenden, der besagt, dass einige Sockets für Server B geöffnet werden, die Server A wie eine Ressource verwenden kann. Möglicherweise gibt es bereits einige Bibliotheken in Python, die dabei helfen.

Ihr aktuelles Design gegeben, Ihr Request hat Zugriff auf den Server als Membervariable, so dass Sie so etwas tun könnte:

class TestServer(SocketServer.TCPServer): 
    def point (self, socketB): 
     self.socketB = socketB # hold serverB socket 

class TestRequestHandler(SocketServer.BaseRequestHandler): 

    def handle(self): 
     data = self.request.recv(1024) 

     if (data): 
      self.request.send(data) 
      print data 

     self.server.socketB ... # Do whatever with the socketB 

Aber wie ich schon sagte, kann es besser sein, dass Sie eine Art haben, des Verbindungspools oder eines anderen Objekts, das Ihren Server B-Socket so verwaltet, dass Ihr Server Ein Handler den Socket nur erhalten/freigeben kann, wenn eingehende Anfragen bearbeitet werden.

Auf diese Weise können Sie besser mit Bedingungen umgehen, bei denen Server B den Socket unterbricht.Ihr derzeitiges Design wäre nicht in der Lage, kaputte Steckdosen sehr einfach zu handhaben. Nur ein paar Gedanken ...

1

Ok, meine Hauptaufgabe ist das. Aufbau des Abhörservers (A-Server - localhost, 6666), der beim Start eine "harte" Verbindung zum anderen Server öffnet (B-Server - localhost, 7777). Wenn der Kunde Daten an den A-Server sendet, sendet dieser (A-Server) Daten (mit dieser harten Verbindung zum B-Server) an B-Server, die Antwort vom B-Server an A-Server und antwortet sendet zum Kunden. Dann noch einmal: der Kunde sendet Daten, A-Server empfängt sie, sendet dann an den B-Server, die Antwort empfängt Daten vom B-Server und A-Server sendet Daten an den Kunden. Und so rund und rund. Die Verbindung zum B-Server wird erst geschlossen, wenn der Server A beendet wird. Alles oben ist der Test, dieses zu machen.

+0

@Ozymet Ich überarbeitete meine Antwort –

Verwandte Themen