2014-12-30 55 views
0

我在此刻实现在C基于节俭(0.4.0)服务++获取客户端的IP地址与C++和遇到的一个问题:如何节俭

有没有办法让客户端的IP地址从服务方法实现内部?我正在使用TNonblockingServer。

提前致谢!

回答

0

Ticket THRIFT-1053描述了一个类似的Java请求。该解决方案基本上允许访问内部(端点)传输并从中检索数据。没有经过真正的测试,为C++构建类似的解决方案应该很容易。由于您使用的是Thrift 0.4.0,因此我强烈建议先查看当前中继(0.9.3)。该TBufferedTransportTFramedTransportTShortReadTransport已经实现了

boost::shared_ptr<TTransport> getUnderlyingTransport(); 

所以上面提到的补丁可能没有必要在所有。

您的TProcessor派生类在获取调用process()时获取两个传输的暂存。如果您覆盖该方法,你应该能够管理对数据的访问,你感兴趣的是:

/** 
* A processor is a generic object that acts upon two streams of data, one 
* an input and the other an output. The definition of this object is loose, 
* though the typical case is for some sort of server that either generates 
* responses to an input stream or forwards data from one pipe onto another. 
* 
*/ 
class TProcessor { 
public: 
    // more code 

    virtual bool process(boost::shared_ptr<protocol::TProtocol> in, 
         boost::shared_ptr<protocol::TProtocol> out, 
         void* connectionContext) = 0; 

    // more code 
1

在TNonblockingServer,当TProcessor ::处理()被称为TProtocol.transport是TMemoryBuffer,所以aquiring客户端IP地址是不可能的。

但我们可以扩展类TServerEventHandler方法当客户端即将调用处理器时,将调用TServerEventHandler :: processContext()。

static boost::thread_specific_ptr<std::string> thrift_client_ip; // thread specific 
class MyServerEventHandler : public TServerEventHandler 
{ 
    virtual void processContext(void* serverContext, boost::shared_ptr<TTransport> transport) 
    { 
     TSocket *sock = static_cast<TSocket *>(transport.get()); 

     if (sock) 
     { 
      //thrift_client_ip.reset(new string(sock->getPeerAddress())); // 0.9.2, reused TNonblockingServer::TConnection return dirty address, see https://issues.apache.org/jira/browse/THRIFT-3270 
      sock->getCachedAddress(); // use this api instead 
     } 
    } 
}; 

// create nonblocking server 
TNonblockingServer server(processor, protocolFactory, port, threadManager); 
boost::shared_ptr<MyServerEventHandler> eventHandler(new MyServerEventHandler()); 
server.setServerEventHandler(eventHandler); 
0
#ifndef NONBLOCK_SERVER_EVENT_HANDLER_H 
#define NONBLOCK_SERVER_EVENT_HANDLER_H 

#include <thrift/transport/TSocket.h> 
#include <thrift/server/TServer.h> 

namespace apache{ 
namespace thrift{ 
namespace server{ 

class ServerEventHandler:public TServerEventHandler{ 
     void* createContext(boost::shared_ptr<TProtocol> input, boost::shared_ptr<TProtocol> output){ 
    (void)input; 
    (void)output; 
    return (void*)(new char[32]);//TODO 
    } 

    virtual void deleteContext(void* serverContext, 
           boost::shared_ptr<TProtocol>input, 
           boost::shared_ptr<TProtocol>output) { 
       delete [](char*)serverContext; 
    } 

    virtual void processContext(void *serverContext, boost::shared_ptr<TTransport> transport){ 
    TSocket *tsocket = static_cast<TSocket*>(transport.get()); 
    if(socket){ 
         struct sockaddr* addrPtr; 
         socklen_t addrLen; 
     addrPtr = tsocket->getCachedAddress(&addrLen); 
        if (addrPtr){ 
             getnameinfo((sockaddr*)addrPtr,addrLen,(char*)serverContext,32,NULL,0,0) ; 
         } 
    } 
    } 
}; 

} 
} 
} 

#endif 

boost::shared_ptr<ServerEventHandler> serverEventHandler(new ServerEventHandler() 
server.setServerEventHandler(serverEventHandler);