2013-01-31 55 views
9

मैं एक नई परियोजना शुरू कर रहा हूं और साथ ही साथ पॉको लाइब्रेरी की खोज की है, जो मुझे बिल्कुल अद्भुत लगता है। हालांकि मैं थोड़ा हारा हूं, क्योंकि उदाहरण बहुत ज्यादा नहीं हैं।पोको :: नेट सर्वर और क्लाइंट टीसीपी कनेक्शन इवेंट हैंडलर

मेरे पास एक सर्वर अनुप्रयोग-> टीसीपीएस सर्वर-> सर्वर सॉकेट + टीसीपीएस सर्वर कनेक्शन कनेक्शन-> टीसीपीएस सर्वर कनेक्शन कनेक्शन उदाहरणों के अनुसार संकेत मिलता है। मैं निर्देशानुसार पोकोनेट कक्षाओं से विरासत में हूं। अभी मैं अपने सर्वर को सेवा के रूप में चला सकता हूं, & इनकमिंग कनेक्शन प्राप्त करता है।

मैं निम्नलिखित के लिए एक ईवेंट हैंडलिंग दृष्टिकोण लेना चाहता हूं: प्रति कनेक्शन (या प्रति ग्राहक) के आधार पर, क्लाइंट सॉकेट पर पढ़ने के लिए उपलब्ध डेटा जैसे ईवेंट को संभालें, क्लाइंट सॉकेट पर त्रुटि हुई (डिस्कनेक्ट या टाइमआउट), क्लाइंट सॉकेट पर त्रुटि के बिना डेटा भेजें।

मैं इसे करने के बारे में कैसे जा सकता हूं? क्या पॉको/फाउंडेशन/घटनाक्रम जो मैं ढूंढ रहा हूं, या क्या पोको :: नेट में कुछ तंत्र लागू किया गया है?

मैंने पोको :: नेट :: नेटएक्सपीक्शन देखा है लेकिन नेटकैट कनेक्शन बंद होने पर उन्हें मेरे टीसीपीएस सर्वर कनेक्शन-व्युत्पन्न वर्ग में फेंकने लगते नहीं हैं।

उत्तर

9

क्या मैं का उपयोग कर समाप्त हो गया एक अलग दृष्टिकोण है के रूप में TCPServer एक अलग जानवर पूरी तरह है। उदाहरण here पोस्ट के बाद मैं एक वर्ग ServerApplication से इनहेरिट, और एक वर्ग जो अनिवार्य रूप से कनेक्शन हैंडलर एक SocketReactor से हो जाता है के साथ समाप्त हो गया।

Deamonizer हैडर:

class Daemon : public ServerApplication 
{ 
    public: 
    Daemon(); 
    /// @Brief The main loop of the daemon, everything must take place here 
    int main(); 
}; 

Deamonizer कार्यान्वयन:

int Daemon::main() 
{ 
    // Server Socket 
    ServerSocket svs(2222); 
    // Reactor-Notifier 
    SocketReactor reactor; 
    Poco::Timespan timeout(2000000); // 2Sec 
    reactor.setTimeout(timeout); 
    // Server-Acceptor 
    SocketAcceptor<ConnectionHandler> acceptor(svs, reactor); 
    // Threaded Reactor 
    Thread thread; 
    thread.start(reactor); 
    // Wait for CTRL+C 
    waitForTerminationRequest(); 
    // Stop Reactor 
    reactor.stop(); 
    thread.join(); 
    return Application::EXIT_OK; 
} 

हैंडलर वर्ग के रूप में लंबे समय के रूप में यह एक अनुरूप निर्माता है कुछ भी हो सकता है (इस के लिए पोको :: नेट दस्तावेज़ देखें)। मेरे मामले में हेडर कुछ इस तरह दिखता है:

:

class ConnectionHandler 
{ 
    public: 

    /** 
    * @Brief Constructor of the Connection Handler 
    * @Note Each object is unique to an accepted connection 
    * @Param SteamSocket is the socket accepting the connections 
    * @See SocketAcceptor http://pocoproject.org/docs/Poco.Net.SocketAcceptor.html 
    * @Param SocketReactor is the reacting engine (threaded) which creates notifications about the socket 
    */ 
    ConnectionHandler(StreamSocket &, SocketReactor &); 

    /** 
    * @Brief Destructor 
    */ 
    ~ConnectionHandler(); 

    /** 
    * @Brief Event Handler when Socket becomes Readable, i.e: there is data waiting to be read 
    */ 
    void onSocketReadable(const AutoPtr<ReadableNotification>& pNf); 

    /** 
    * @Brief Event Handler when Socket was written, i.e: confirmation of data sent away (not received by client) 
    */ 
    void onSocketWritable(const AutoPtr<WritableNotification>& pNf); 

    /** 
    * @Brief Event Handler when Socket was shutdown on the remote/peer side 
    */ 
    void onSocketShutdown(const AutoPtr<ShutdownNotification>& pNf); 

    /** 
    * @Brief Event Handler when Socket throws an error 
    */ 
    void onSocketError(const AutoPtr<ErrorNotification>& pNf); 

    /** 
    * @Brief Event Handler when Socket times-out 
    */ 
    void onSocketTimeout(const AutoPtr<TimeoutNotification>& pNf); 

    private: 

    /** 
    * @Brief Read bytes from the socket, depending on available bytes on socket 
    */ 
    void readBytes(); 

    /** 
    * @Brief Send message to the socket 
    * @Param std::string is the message (null terminated) 
    */ 
    void sendMessage(std::string); 

    /// Stream Socket 
    StreamSocket _socket; 

    /// Socket Reactor-Notifier 
    SocketReactor& _reactor; 

    /// Received Data Buffer 
    std::vector<char *> in_buffer; 
}; 

आप हैंडलर कैसे लागू आप पर निर्भर है, केवल एक चीज है कि आप क्या करने की जरूरत रजिस्टर है वर्ग तरीकों जो इतनी तरह की घटनाओं को संभाल प्रदान की

_reactor.addEventHandler(_socket,NObserver<ConnectionHandler, ReadableNotification>(*this, &ConnectionHandler::onSocketReadable)); 
    _reactor.addEventHandler(_socket,NObserver<ConnectionHandler, ShutdownNotification>(*this, &ConnectionHandler::onSocketShutdown)); 
    _reactor.addEventHandler(_socket,NObserver<ConnectionHandler, ErrorNotification>(*this, &ConnectionHandler::onSocketError)); 
    _reactor.addEventHandler(_socket,NObserver<ConnectionHandler, TimeoutNotification>(*this, &ConnectionHandler::onSocketTimeout)); 

सब कुछ, दो वर्ग, कोड की कुछ पंक्तियां, सरल और साफ। बिल्कुल पोको पुस्तकालय प्यार करना शुरू कर दिया! :)

+0

अच्छा रिएक्टर :) धन्यवाद Alex –

8

इस के साथ प्रयास करें:

#include <iostream> 
#include "Poco/Net/TCPServer.h" 
#include "Poco/Net/TCPServerParams.h" 
#include "Poco/Net/TCPServerConnectionFactory.h" 
#include "Poco/Net/TCPServerConnection.h" 
#include "Poco/Net/Socket.h" 
using namespace std; 

class newConnection: public Poco::Net::TCPServerConnection { 
public: 
    newConnection(const Poco::Net::StreamSocket& s) : 
     Poco::Net::TCPServerConnection(s) { 
    } 

    void run() { 
     cout << "New connection from: " << socket().peerAddress().host().toString() << endl << flush; 
     bool isOpen = true; 
     Poco::Timespan timeOut(10,0); 
     unsigned char incommingBuffer[1000]; 
     while(isOpen){ 
      if (socket().poll(timeOut,Poco::Net::Socket::SELECT_READ) == false){ 
       cout << "TIMEOUT!" << endl << flush; 
      } 
      else{ 
       cout << "RX EVENT!!! ---> " << flush; 
       int nBytes = -1; 

       try { 
        nBytes = socket().receiveBytes(incommingBuffer, sizeof(incommingBuffer)); 
       } 
       catch (Poco::Exception& exc) { 
        //Handle your network errors. 
        cerr << "Network error: " << exc.displayText() << endl; 
        isOpen = false; 
       } 


       if (nBytes==0){ 
        cout << "Client closes connection!" << endl << flush; 
        isOpen = false; 
       } 
       else{ 
        cout << "Receiving nBytes: " << nBytes << endl << flush; 
       } 
      } 
     } 
     cout << "Connection finished!" << endl << flush; 
    } 
}; 

int main(int argc, char** argv) { 

    //Create a server socket to listen. 
    Poco::Net::ServerSocket svs(1234); 

    //Configure some server params. 
    Poco::Net::TCPServerParams* pParams = new Poco::Net::TCPServerParams(); 
    pParams->setMaxThreads(4); 
    pParams->setMaxQueued(4); 
    pParams->setThreadIdleTime(100); 

    //Create your server 
    Poco::Net::TCPServer myServer(new Poco::Net::TCPServerConnectionFactoryImpl<newConnection>(), svs, pParams); 
    myServer.start(); 

    while(1); 

    return 0; 
} 
+0

सीज़र के उत्तर के लिए धन्यवाद, लेकिन यह सवाल का जवाब नहीं देता है। आपका उदाहरण केवल कनेक्शन स्वीकार करता है, जबकि मैं जो मांग रहा हूं वह एक चुनिंदा या (ई) मतदान या इवेंट हैंडलर आने वाले डेटा के लिए स्वीकृत कनेक्शन पर, त्रुटियों, आदि –

+0

उदाहरण इनकमिंग कनेक्शन, टाइमआउट, नेटवर्क त्रुटियों आदि के साथ पूरा उदाहरण है। .. –

+0

फिर, बहुत बहुत धन्यवाद :) –