2014-07-18 3 views
1

C++ 서버로 작성한 서버는 프록시처럼 작동합니다. 주요 기능 : 지금은C++의 멀티 스레드 서버, 스레드를 종료하고 멋지게 정리하는 방법

try 
{ 
    Connector c(ip); //establishes persistent connection to the server B 
    Listener1 l1(port); //listens incoming connection to the server A (our proxy) and push them into the queue 
    Listener2 l2(&c); //listens responses (also push messages) from the server B and push them into the queue 
    Proxy p(&c, &l1, &l2); //pulls clients out from the queue and forwards requests to the server B, pull out everything from the listener2 queue and returns as a responce 
    KeepAlive k(&l1, &p); //pushes the empty client to the listeners1's queue thus the proxy sends keepalive to the server B and the response is discarded 
    l1.start(); 
    p.start(); 
    l2.start(); 
    k.start(); 
    l1.join(); 
    p.join(); 
    l2.join(); 
    k.join(); 
catch(std::string e) 
{ 
    std::cerr << "Error: " << e << std::endl; 
    return -1; 
} 

I 온 문제/의문은 다음과 같습니다.

** 1 ** 나는 그것이 좋은 방법입니다, 생성자에서 예외를 던져? 연결을 설정할 수 없을 때 예외가 발생합니다. 그 이유는 객체가 만들어지지 않아야하기 때문입니다.

** 2 ** 응용 프로그램 안전을 종료하고 연결 시간 초과가 발생하거나 서버 B가 연결을 종료 할 때 정리하는 데 문제가 있습니다. listener1과 listener2는 차단 함수 (시스템 호출 accept()와 openssl lib의 BIO_read)를 사용하므로 다른 스레드에서 루프 조건을 설정하는 것은 불가능합니다. 문제는 모든 모듈이 뮤텍스를 사용하여 연결되고 자원을 공유한다는 사실이다. 현재 사용중인 코드는 exit 함수를 호출하여 전체 애플리케이션을 종료합니다.

나는 이것이 완벽한 해결책이 아니라는 것을 알고 있으며, 조언과 조언에 감사드립니다.

미리 감사드립니다.

답변

2

생성자가 실패 할 경우 예외를 throw해야합니다. C++은 그 우물을 처리하도록 설계되었습니다. 기본 클래스와 멤버는 이미 생성 된 경우에만 정리됩니다.

다른 라이브러리의 차단 기능은 항상 문제가됩니다. Windows와 POSIX는 잘 처리합니다 : WSAWaitForMultipleObjectExselect을 사용하면 대기를 차단 해제하는 데 사용할 수있는 추가 핸들을 추가 할 수 있습니다.

accept 호출에서 로컬 호스트를 통해 주 스레드에서 연결을 생성하여 가짜로 만들 수 있습니다. 이 "비정상적인"연결을 감지하면 더 이상의 연결을 허용하지 않을 것입니다.

openSSL을 읽을 때, 나는 주 스레드에서 소켓을 닫을 뿐이며 threadsafety는 저주받을 것입니다. 나는 셧다운에서 이것을 아주 늦게 할 것이고, 그 시점 이후에는 라이브러리가 전혀 쓸모 없다고 기대할 것이다.

관련 문제