2014-04-09 2 views
0

에코 예제에서 설명한대로 Poco SocketReactor를 구현하는 코드가 있습니다. 또한 내가 그것을 테스트하는 파이썬 클라이언트가이상한 포코 반응기 알림

Poco::Net::ServerSocket tcpsock("9495"); 
Poco::Net::SocketReactor reactor; 
Poco::Net::SocketAcceptor<TSPConnectionHandler> acceptor(tcpsock, reactor); 
Poco::Thread thread; 
thread.start(reactor); 

waitForTerminationRequest(); 

reactor.stop(); 
thread.join(); 
return Application::EXIT_OK; 

:

class TSPConnectionHandler 
{ 
    public: 
     TSPConnectionHandler(const StreamSocket& socket, SocketReactor& reactor) :  _socket(socket), 
                        _reactor(reactor) 
     { 
      _reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ReadableNotification>(*this, &TSPConnectionHandler::onSocketReadable)); 
      _reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, WritableNotification>(*this, &TSPConnectionHandler::onSocketWritable)); 
      _reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ShutdownNotification>(*this, &TSPConnectionHandler::onSocketShutdown)); 
      _reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ErrorNotification>(*this, &TSPConnectionHandler::onSocketError)); 
      _reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, TimeoutNotification>(*this, &TSPConnectionHandler::onSocketTimeout)); 
     } 
     virtual ~TSPConnectionHandler() 
     { 
      _reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ReadableNotification>(*this, &TSPConnectionHandler::onSocketReadable)); 
      _reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, WritableNotification>(*this, &TSPConnectionHandler::onSocketWritable)); 
      _reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ShutdownNotification>(*this, &TSPConnectionHandler::onSocketShutdown)); 
      _reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ErrorNotification>(*this, &TSPConnectionHandler::onSocketError)); 
      _reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, TimeoutNotification>(*this, &TSPConnectionHandler::onSocketTimeout)); 
     } 

    void onSocketReadable(const Poco::AutoPtr<ReadableNotification>& pNf) 
    { 
     cout << "READable !!" << endl; 
     try 
     { 
     vector<char> m_buffer; 
     m_buffer.resize(1024, '\0'); 
     LONG32 m_buflen = _socket.receiveBytes(&m_buffer[0], 1024); 
     if (m_buflen == 0) 
     { 
      cout << "Connection reset by peer normally" << endl; 
      delete this; 
     } 
     _socket.sendBytes(&m_buffer[0], m_buflen); 
     } 
     catch(Poco::Net::NetException& e) 
     { 
      cout << "socket read exception: " << e.displayText() << endl; 
      delete this; 
     } 
    } 
    void onSocketWritable(const Poco::AutoPtr<WritableNotification>& pNf) 
    { 
     cout << "WRITEable !!" << endl; 
    } 
    void onSocketShutdown(const Poco::AutoPtr<ShutdownNotification>& pNf) 
    { 
     cout << "SHUTDOWN!!!!!!!!!!!!" << endl; 
     delete(this); 
    } 
    void onSocketError(const Poco::AutoPtr<ErrorNotification>& pNf) 
    { 
     cout << "Error!!" << endl; 
    } 
    void onSocketTimeout(const Poco::AutoPtr<TimeoutNotification>& pNf) 
    { 
     cout << "Timeout!!" << endl; 
    } 

    private: 
     StreamSocket _socket; 
     SocketReactor& _reactor; 
}; 

은이 코드를 사용하여 프로그램에서 일반적으로 다른 곳에서 시작

import socket 

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
client_socket.connect(('localhost', 9495)) 
data = raw_input ("Something:") 
client_socket.send(data) 
data = client_socket.recv(1024) 
print "RECIEVED:" , data 
client_socket.close() 

을 그리고 질문의 목록을 얻었다을하는 I 돈 해결 방법을 이해해야합니다.

  • 파이썬 문자열 "client_socket.connect ((''localhost ', 9495))"가 완료되면 서버는 "onSocketWritable"스팸 메일을 시작합니다. 어떻게 중지합니까? 나는 소켓이 쓰기 가능한 상태가되면 알림을 받아야한다는 것을 이해하지만, 왜 모든 소켓의 수명 동안 그것을 계속 하는가? 그것이 정상적인 상황이라면 WritableNotification을 위해 설계된 것은 무엇입니까?
  • 파이썬을 디버그 모드로 시작하고 "client_socket.close()"전에 닫으면 서버가 예외를 얻고 삭제됩니다. "소켓 읽기 예외 :"가 발생합니다. 그러나 오류 통지 및 종료 알림은 발송되지 않습니다. 왜? 나는 그들이 어떻게 든 파견되는 것을 보지 못했다.
  • "client_socket.close()"를 서버 측에서 처리하게하려면 ReadableNotification을 수신하고 "Peer by Connection normal by connection normal"을 throw합니다. 그러나 여전히 ShutdownNotification은 없습니다. 왜? 당신은 소켓이 인스턴스화 될 서버에 연결하고 쓰기 가능한 알림을 registred 경우이 상태에 대한 알림을 받게됩니다하자마자

답변

2
  1. . 이것은 데이터를 보낼 때만이 이벤트 처리기를 추가한다는 것을 의미합니다. 소켓은 데이터를 보내고 완료되면이 핸들러가 다시 호출됩니다 (비동기 소켓 ...). 이 이벤트에 대해 블록 호출을 더 보낼 필요가없는 경우 removeEventHandler를 호출하십시오.

  2. 소켓 반응기가 선택 명령을 사용하여 (소켓 선택 :: (읽기, 쓰기, 제외 _TIMEOUT))라는 이름 errornotification는 오해의 소지가 조금 (일부 오류 조건을 얻을뿐만 아니라 경계 데이터의 출력됩니다)입니다. 소켓이 정상적으로 닫히면 (자) onReadable는 사용 가능한 char가없는 경우에 불려갑니다. 그렇지 않은 경우는 Poco :: Net :: ConnectionResetException가 Throw됩니다.

  3. ShutdownNotification은 SocketReactor가 중지되면 전송됩니다.

당신은 SocketRactor.cpp를 살펴 봐야합니다. 그러면 모든 것이 훨씬 명확 해집니다.

관련 문제