2013-05-12 12 views
6

Próbuję stworzyć serwer TCP z bibliotekami POCO C++. Znalazłem kilka przykładów: here. Najpierw spróbowałem przykładu od Alexa, ale zdarzenie zamknięcia nie działało. EchoServer ma ten sam problem. Więc, spróbowałem przykładu Cesara Ortiza i dostałem niezwykły problem. Po pewnym czasie serwer zgłasza błąd:Serwer wielowątkowy TCP z bibliotekami POCO C++

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
["src/ErrorHandler.cpp", line 60] 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

Połączenia otrzymały również błąd limitu czasu połączenia, również nowe połączenia. Przykład z semeedem obsługi zdarzeń jest bardziej poprawny, ale nie wiem, jak mogę naprawić zdarzenie shutdown.

Odpowiedz

12

Jeśli wszystko czego potrzebujesz, to wielowątkowy serwer TCP, to zrobi to "z pudełka" Poco::Net::TCPServer - jest wewnętrznie wielowątkowy. Zacznij od zdefiniowania połączenia, ten po prostu echo cokolwiek wysłać do niego:

class EchoConnection: public TCPServerConnection { 
public: 
    EchoConnection(const StreamSocket& s): TCPServerConnection(s) { } 

    void run() { 
    StreamSocket& ss = socket(); 
    try { 
     char buffer[256]; 
     int n = ss.receiveBytes(buffer, sizeof(buffer)); 
     while (n > 0) { 
     ss.sendBytes(buffer, n); 
     n = ss.receiveBytes(buffer, sizeof(buffer)); 
     } 
    } 
    catch (Poco::Exception& exc) 
    { std::cerr << "EchoConnection: " << exc.displayText() << std::endl; } 
    } 
}; 

Następnie należy uruchomić serwer i wysłać go niektóre dane:

TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>()); 
srv.start(); 

SocketAddress sa("localhost", srv.socket().address().port()); 
StreamSocket ss(sa); 
std::string data("hello, world"); 
ss.sendBytes(data.data(), (int) data.size()); 
char buffer[256] = {0}; 
int n = ss.receiveBytes(buffer, sizeof(buffer)); 
std::cout << std::string(buffer, n) << std::endl; 

srv.stop(); 
+0

Dzięki za odpowiedź Alex. Jak już powiedziałem, teraz używam drugiego przykładu podobnego do twojego, ale nie mogę znaleźć przyczyny błędu z komunikatem "src/errorhandler.cpp". Po tym serwerze akceptuje połączenia, ale nie wysyła ani nie przyjmuje bajtów dla nowych połączeń i rzucać "limit czasu połączenia" dla istniejących połączeń. –

+0

Musisz wyrzucać wyjątek gdzieś w module obsługi połączenia. Ponieważ działa w wątku, kończy się domyślną obsługą błędów. Wyjątek prawdopodobnie nie jest potomkiem ze std :: exception, więc ErrorHandler nic o nim nie wie. Ale nie dostarczasz wystarczających informacji, aby uzyskać konkretną odpowiedź na temat problemu. Najlepiej uruchomić kod w debugerze i przejść przez niego, aby znaleźć źródło problemu. – Alex

+0

Jak powiedziałem, używam przykładu Cesara Ortiza, właśnie zmieniłem funkcję "uruchom" - [tutaj] (http://hastebin.com/lokadobeve.coffee) Jak się dowiedziałem, kiedy połączenie nie mogło uzyskać danych ponieważ jest w kolejce, ale nie rozumiem, dlaczego? Gdy bieżące połączenia osiągną 16, wszystkie nowe połączenia zostaną dodane do kolejki i odrzucone później. W parametrach ustawiłem maxqueued (3), maxthreads (20) i threadidletime (100) –