2009-02-07 2 views
4

C++ (Win32)의 인스턴트 메신저 클라이언트에서 작업 중이며 다른 비동기 소켓 모델을 실험하고 있습니다. 지금까지 나는 메인 윈도우를 통해 알림을 수신하기 위해 WSAAsyncSelect을 사용 해왔다. 그러나, 나는 하나의 단일 소켓에 대해 WSAAsyncSelect를 호출 할 때 생성 된 초기 스레드 외에 추가로 5-6 스레드를 생성하는 Winsock에서 예상치 못한 결과를 경험했습니다.인스턴트 메신저 클라이언트에 가장 적합한 비동기 소켓 모델은 무엇입니까?

DLL을 통해 추가 프로토콜을 지원하기 위해 클라이언트를 개편 할 계획이 있습니다. 그리고 현재의 솔루션이 WSAAsyncSelect에 대한 내 경험에 기반하여 적합하지 않을까 봐 걱정됩니다. UI 코드 (메시지 루프에서).

약 10-20 + 연결 (프로토콜 및 프로토콜 디자인의 양에 따라 다름)을 처리 할 수 ​​있어야하는 다중 프로토콜 IM 클라이언트에 적합한 비동기 소켓 모델에 대한 조언을 찾고 있습니다. 등), 과도한 양의 스레드를 사용하지 않는 동안 - 나는 성능에 관심이 많고 리소스 사용량을 줄입니다.

나는 IO Completion Ports를보고 있었지만, 내가 모은 것에서는 과잉으로 보인다. 적절한 소켓 솔루션이 무엇인지에 대한 의견을 많이 보내 주시면 감사하겠습니다.

미리 감사드립니다. :-)

답변

5

여러 동시 소켓을 처리하는 네 가지 기본 방법이 있습니다.

  1. 멀티플렉싱은 select()를 사용하여 소켓을 폴링합니다.
  2. AsyncSelect는 기본적으로 WSAAsyncSelect로 수행중인 작업입니다.
  3. Worker Threads, 각 연결마다 단일 스레드를 생성합니다.
  4. IO 완료 포트 또는 IOCP. dp는 위에서 언급했지만 기본적으로 비동기 입출력을 처리하는 OS 고유의 방법으로 성능은 좋지만 조금 혼란 스럽습니다.

자주가는 곳에 따라 선택합니다. 응용 프로그램을 다른 플랫폼에 이식하려는 경우 select가 다른 OS에서 사용되는 다른 모델과 크게 다르지 않으므로 # 1 또는 # 3을 선택하고 대부분의 다른 OS에도 스레드 개념이 있습니다 (단, 다르게 작동). IOCP는 일반적으로 윈도우에만 해당됩니다 (Linux에는 현재 일부 비동기 I/O 기능이 있지만).

앱이 Windows 전용 인 경우 기본적으로하고있는 작업에 가장 적합한 모델을 선택하고 싶습니다. 아마도 # 3 또는 # 4 일 것입니다. # 4가 응용 프로그램을 호출 할 때 가장 효율적입니다 (유사하지만 WSAsyncSelect에 대한 성능 및 문제가 적음).

스레드 (IOCP 또는 WorkerThreads)를 사용할 때 처리해야 할 중요한 사항은 작업자 스레드에서 UI 함수를 호출 할 수 없기 때문에 UI를 업데이트 할 수있는 스레드로 데이터를 마샬링하는 것입니다. 궁극적으로 이것은 대부분의 경우 앞뒤로 일부 메시징을 포함합니다.

관리 코드에서 이것을 개발한다면 제프리 리히터 (Jeffrey Richter)의 AysncEnumerator를 살펴 보도록 하겠지만, 장단점이있는 C++을 선택했습니다. 많은 사람들이 C++을위한 다양한 네트워크 라이브러리를 작성했습니다. 아마도 여러분은 그들 중 일부를 연구하는데 약간의 시간을 할애해야 할 것입니다.

+0

# 제프리 리히터의 AysncEnumerator #wow !!! – divinci

3

부스트 (www.boost.org)에서 찾을 수있는 ASIO 라이브러리를 사용하는 것을 고려하십시오.

2

어떤면에서 IOCP (IO Completion Ports)는 잔인한 부분이지만 솔직히 대안 (비 차단 소켓 선택, 겹친 IO 등)보다 비동기 소켓 모델을 사용하는 것이 더 쉽습니다.

IOCP API는 더 명확해질 수 있지만 일단 지나면 실제로 사용하기가 더 쉽습니다. 가장 큰 장애물은 플랫폼 지원이었습니다 (NT 기반 OS가 필요했습니다. 즉, Windows 9x는 IOCP를 지원하지 않았습니다). 그 제한이 오래 지쳐서, 나는 그것을 고려할 것입니다.

3

동기 모델 만 사용하십시오. 최신 운영 체제는 여러 스레드를 잘 처리합니다. 비동기 IO는 드문 상황, 대개 서버에서 필요합니다.

2

IOCP를 사용하기로 결정한 경우 (Windows 용으로 작성한 경우 IMHO가 가장 좋습니다) 사용 가능한 많은 코드가있어 필요한 작업이 많이 걸립니다. .

코드의 최신 버전과 원본 기사 링크는 here에서 얻을 수 있습니다.

내 프레임 워크가 Boost :: ASIO와 비교되는 방식에 대한 의견은 여기 http://www.lenholgate.com/blog/2008/09/how-does-the-socket-server-framework-compare-to-boostasio.html에서 확인할 수 있습니다.

+0

매우 유용한 기사입니다. 고맙습니다. – haste

+0

오, 제가 언급하지 않은 한가지; IOCP 스레드에서 GUI 스레드로 마샬링하는 문제는 소켓 래퍼 객체와 버퍼 객체가 모두 참조된다는 사실에 의해 (내 프레임 워크에서) 도움이된다. 단순히 AddRef() 그들과 Windows 메시지에 params로 게시 ... –

관련 문제