2

これは問題です。私の主な仕事は、「s」オブジェクトを TestRequestHandler クラスの「handle」メソッドに渡すことです。私の最初のステップは、「ポイント」メソッドを介して「s」オブジェクトをTestServerクラスに配信することでしたが、ここで立ち往生しました。「s」オブジェクトを TestRequestHandler に配信するには? いくつかの提案?

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()
4

3 に答える 3

2

If I understand correctly, I think you perhaps are misunderstanding how the module works. You are already specifying an address of 'localhost:6666' for the server to bind on.

When you start the server via your call to serve_forever(), this is going to cause the server to start listening to a socket on localhost:6666.

According to the documentation, that socket is passed to your RequestHandler as the 'request' object. When data is received on the socket, your 'handle' method should be able to recv/send from/to that object using the documented socket API.

If you want a further abstraction, it looks like your RequestHandler can extend from StreamRequestHandler and read/write to the socket using file-like objects instead.

The point is, there is no need for you to create an additional socket and then try to force your server to use the new one instead. Part of the value of the SocketServer module is that it manages the lifecycle of the socket for you.

On the flip side, if you want to test your server from a client's perspective, then you would want to create a socket that you can read/write your client requests on. But you would never pass this socket to your server, per se. You would probably do this in a completely separate process and test your server via IPC over the socket.

Edit based on new information

To get server A to open a socket to server B when server A receives data one solution is to simply open a socket from inside your RequestHandler. That said, there are likely some other design concerns that you will need to address based on the requirements of your service.

For example, you may want to use a simple connection pool that say opens a few sockets to server B that server A can use like a resource. There may already be some libraries in Python that help with this.

Given your current design, your RequestHandler has access to the server as a member variable so you could do something like this:

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

But like I said, it may be better for you to have some sort of connection pool or other object that manages your server B socket such that your server A handler can just acquire/release the socket as incoming requests are handled.

This way you can better deal with conditions where server B breaks the socket. Your current design wouldn't be able to handle broken sockets very easily. Just some thoughts...

于 2009-04-02T22:39:47.617 に答える
1

わかりました、私の主な仕事はこれです。開始時に別のサーバー (B サーバー - localhost、7777) への「ハード」接続を開くリッスン サーバー (A サーバー - localhost、6666) の構築。顧客が A サーバーにデータを送信すると、この (A サーバー) は (B サーバーにハード接続された) データを B サーバーに送信し、回答は B サーバーから A サーバーに受信され、回答が B サーバーに送信されます。顧客。次に、顧客がデータを送信し、Aサーバーがデータを受信して​​からBサーバーに送信し、回答がBサーバーからデータを受信し、Aサーバーがデータを顧客に送信します。そしてぐるぐる。B サーバーへの接続は、サーバー A が停止する直前に閉じられます。以上が、これを作るためのテストです。

于 2009-04-03T08:06:07.757 に答える
1

s の値が一度設定され、再初期化されていない場合は、TestServer のインスタンス変数ではなくクラス変数にして、ハンドラーのコンストラクターで TestServer のクラス メソッドを介してハンドラーに取得させることができます。

例: TestServer._mySocket = s

于 2009-04-02T18:42:07.110 に答える