2009-04-02 7 views
2

이것은 문제입니다. 나의 주요 연구 대상은 "TestRequestHandler"클래스의 "handle"메소드에 "s"객체를 전달하는 것이다. 첫 번째 단계는 "point"메서드를 통해 "Test"클래스에 "s"개체를 전달하지만 여기서는 멈추었습니다. "s"객체를 TestRequestHandler에 전달하는 방법? 몇 가지 제안?SocketServer.BaseRequestHandler의 인스턴스에 개체의 인스턴스를 전달하는 방법?

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

혼란 스럽습니다. 서버가 localhost : 6666에서 소켓을 여는 중입니다. 당신이 만들고있는 "소켓"이란 무엇입니까? 그게 테스트를위한 클라이언트 소켓이되어야합니까? –

+0

나는 또한 약간 혼란 스럽다. "전달"이란 스레드 간 통신을 말하는 것입니까? 아니면 원격 프로 시저를 호출하려고합니까? 객체를 서버로 전송합니다. 나는 당신이 "요점"을 의미하는지 이해하지 못한다고 고백합니다. –

답변

1

의의 값이 한 번 설정하고 다시 초기화되어 있지 않은 경우 - 당신은 그것을 TESTSERVER의 인스턴스 변수에 반대 클래스 변수 확인한 다음 핸들러가 TESTSERVER의 클래스 방법을 통해 검색 할 수 핸들러의 생성자.

예 : TestServer._mySocket =의

2

만약 내가 제대로 이해하고, 내가 모듈이 작동하는 방법 당신은 아마 오해 생각합니다. 바인드 할 서버에 이미 'localhost : 6666'의 주소를 지정하고 있습니다.

serve_forever() 호출을 통해 서버를 시작하면 서버가 localhost : 6666의 소켓 수신을 시작하게됩니다.

문서에 따르면 소켓은 RequestHandler에 'request'객체로 전달됩니다. 데이터가 소켓에서 수신되면 'handle'메소드는 문서화 된 소켓 API를 사용하여 해당 객체에서 수신/송신 할 수 있어야합니다.

더 이상 추상화하려는 경우 RequestHandler가 StreamRequestHandler에서 확장하고 대신 파일과 유사한 객체를 사용하여 소켓에 읽고 쓸 수있는 것처럼 보입니다.

요점은 추가 소켓을 생성 한 다음 서버가 새 소켓을 사용하도록 강제 할 필요가 없다는 것입니다. SocketServer 모듈의 가치 중 일부는 소켓의 수명주기를 관리한다는 것입니다.

클라이언트 측면에서 서버를 테스트하려면 클라이언트 요청을 읽고 쓸 수있는 소켓을 만들고 싶습니다. 그러나 당신은 결코이 소켓을 서버에 넘기지 않을 것입니다. IPC를 통해 소켓을 통해 서버를 테스트하고 완전히 분리 된 프로세스에서이 작업을 수행 할 수 있습니다. 새로운 정보

에 따라

편집 서버 A는 하나 개의 솔루션은 단순히 RequestHandler를 내부에서 소켓을 열 수 있습니다 데이터를 수신 할 때 서버 B에 소켓을 열 서버 A를 얻으려면. 즉, 서비스 요구 사항에 따라 해결해야 할 몇 가지 다른 디자인 문제가있을 수 있습니다.

예를 들어 서버 A가 리소스처럼 사용할 수있는 서버 B에 몇 개의 소켓을 여는 간단한 연결 풀을 사용할 수 있습니다. 파이썬에는 이미 도움이되는 라이브러리가있을 수 있습니다.

은이 같은 것을 할 수있는 귀하의 RequestHandler를가 멤버 변수로 서버에 액세스 할 수있는, 현재의 디자인을 감안할 때 :

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 

을하지만 말했듯이 당신이 어떤 종류를하기가 더 좋을 수 있습니다 연결 풀 또는 서버 B 핸들러가 수신 요청이 처리 될 때 소켓을 획득/해제 할 수 있도록 서버 B 소켓을 관리하는 다른 오브젝트

이렇게하면 서버 B가 소켓을 끊는 조건을 더 잘 처리 할 수 ​​있습니다.현재 디자인으로는 깨진 소켓을 매우 쉽게 처리 할 수 ​​없습니다. 그냥 몇 가지 생각 ...

1

좋아, 내 주요 작업은 이것입니다. 시작하는 동안 다른 서버 (B-server-localhost, 7777)에 "하드"연결을 열어주는 청취 서버 (A-server-localhost, 6666)의 구성. 고객이 A- 서버로 데이터를 보내면이 (A- 서버)가 B- 서버에 대한 하드 연결이있는 데이터를 B- 서버로 전송하고, B- 서버에서 A- 서버로 응답을 보내고 응답을 보냅니다 고객에게. 다시 : 고객이 데이터를 보내고 A- 서버가 데이터를 수신 한 다음 B- 서버로 보냅니다. 응답은 B- 서버에서 데이터를 수신하고 A- 서버는 데이터를 고객에게 보냅니다. 이렇게 둥근. B 서버 연결은 서버 A가 중지 될 때 닫힙니다. 위의 내용은이 모든 것을 테스트 한 것입니다.

+0

@Ozymet 나는 나의 반응을 수정했다. –