2009-10-06 2 views
0

10 개 (또는 그 이상) 다른 클라이언트의 연결을 허용 할 수있는 서버 프로그램이 있다고 가정 해 보겠습니다. 클라이언트는 서버가 수신 한 임의의 데이터를 전송하지만 적어도 하나의 클라이언트가 모든 업데이트 데이터를 전송할 것입니다. 서버는 다른 처리가 있기 때문에 정보가 도착할 때까지 기다릴 수 없습니다. 비동기 소켓을 사용하는 것 외에도 두 가지 옵션이 있습니다.여러 개의 소켓을 사용 중입니까?

  1. 모든 소켓을 비 블로킹으로 만듭니다. 각 소켓에서 recv()을 호출하고 사용 가능한 데이터가없고으로 실패하면 허용하고 일부 데이터를 얻은 다음 보관하십시오.

  2. 소켓을 차단 상태로 둡니다. 모든 소켓을 FD_SET에 추가하고 select()으로 전화하십시오. 반환 값이 0이 아닌 경우 (대부분의 시간이 됨) 모든 소켓을 반복하여 FD_ISSET()과 함께 읽을 수있는 소켓의 적절한 수를 찾고 읽을 수있는 소켓에 recv() 만 호출합니다.

첫 번째 옵션은 recv() 함수를 더 많이 호출합니다. 두 번째 방법은 프로그래밍의 관점에서 보면 FD_SETFD_ISSET 루핑이 모두 발생하므로 큰 고통입니다.

선호되는 방법 (또는 다른 방법)은 무엇입니까? recv()select()이라는 번거 로움이없는 논 블로킹 소켓에서 사용할 수 없게하는 오버 헤드를 피하고 있습니까?

나는 두 가지 방법을 모두 이해하고 있으며 두 가지를 모두 시도했다고 생각하지만 한 가지 방법이 더 좋고 최적인지는 잘 모릅니다.

답변

1

대신 overlapped IO을 사용하는 것이 좋습니다. 그런 다음 WSARecv()을 시작하고 작업 완료시 호출 할 콜백 함수를 제공 할 수 있습니다. 또한 프로그램이 경고 대기 상태 일 때만 호출되므로 스레드 응용 프로그램 에서처럼 잠금에 대해 걱정할 필요가 없습니다 (주 스레드에서 실행한다고 가정 할 때).

그러나 과 같이 경고 대기 상태로 자주 들어가야합니다. 이것이 UI 스레드 인 경우 을 메시지 루프에 사용하고 MWMO_ALERTABLE 플래그를 사용하십시오. 그러면 콜백에 기회가 주어집니다. 비 UI 스레드에서는 경고 대기 상태가되는 wait functions 중 하나를 정기적으로 호출하십시오.

모달 대화 상자는 일반적으로 MsgWaitForMultipleObjectsEx()을 호출하지 않는 자체 메시지 루프를 가지고 있기 때문에 경고 대기 상태가되지 않습니다. 대화 상자를 표시 할 때 네트워크 IO를 처리해야하는 경우 정기적으로 경고 대기 상태가되는 전용 스레드에서 모든 네트워크 IO를 수행하십시오.

어떤 이유에서든 중복 된 IO를 사용할 수 없으면 차단 select()을 사용하십시오. 무한 루프에서와 같이 non-blocking recv()을 사용하는 것은 용서 할 수없는 CPU 시간 낭비입니다. 그러나 소켓을 비 블로킹 모드로 설정하십시오. 그렇지 않으면 한 바이트가 도착하고 두 개를 읽으려고하면 예기치 않게 블로킹 될 수 있습니다.

라이브러리를 사용하여 까다로운 세부 정보를 추상화하는 것이 좋습니다. 예 : libevent 또는 boost::asio.

+0

감사합니다. 이 구현에서는 오버랩 IO를 사용하고 싶지 않지만 제안에 감사드립니다. 나는 그것을 들여다 볼 것이다. 비 차단 모드와 select() 사용에 대한 귀하의 제안을 이해합니다. 내 주요 질문은 recv를 아무 이유없이 호출해야하거나 select()를 호출하는 동작을 거쳐야했다. 답장을 보내 주셔서 감사합니다! – JPhi1618

+0

은 조금 더 명확하게 업데이트했습니다. 단지'recv()'가 CPU를 100 % 페그하려고 할 때 루프를 돌리는 것이 결코 좋은 일이 아닙니다. – bdonlan

0

IO는 연결 당 하나의 스레드로 완전히 차단되어야하며이 경우 이벤트 루프는 본질적으로 OS 스케줄러이거나 IO가 완전히 비 차단이어야하며이 경우에는 select/waitformultipleobjects 기반 이벤트 루프가 필요합니다.

모든 중간 변종 동시 연결의 양이 증가하고 스레드 컨텍스트 스위치 오버 헤드가없는 경우

완전히 비 차단 방식이 훨씬 더 확장 매우 유지 보수 및 경향이 오류가없는 응용 프로그램에서, 그래서 그것은이다 동시 연결 수가 고정되어 있지 않은 곳에서는 더 좋습니다. 이 접근법은 완전히 차단하는 것보다 구현 복잡성이 더 큽니다.

완전히 차단되지 않는 IO의 경우 응용 프로그램의 핵심은 select/waitformultipleobjects 기반 이벤트 루프이며 모든 소켓은 비 블로킹 모드이며 모든 읽기/쓰기는 일반적으로 이벤트 루프 스레드 내에서 수행됩니다 (맨 위 쓰기를 요청하는 스레드에서 직접 성능 쓰기를 시도 할 수 있습니다.)

관련 문제