2009-12-30 2 views
0

WSAASyncSelect를 사용하여 소켓을 비동기 모드로 설정하는 소켓 라이브러리에 문제가 있습니다. 비동기 모드에서 소켓은 비 블로킹 모드 (WSAWOULDBLOCK은 차단되는 모든 작업에서 반환 됨)에 놓이고, 소켓 메시지를 읽을 준비가되었을 때 응용 프로그램에 알리기 위해 윈도우 메시지가 알림 창에 게시됩니다.비동기 소켓에서 데이터를 최적으로 읽음

내 문제는 이것입니다. FD_READ 이벤트를 수신하면 시도하고 recv 할 바이트 수를 알 수 없습니다. 버퍼가 너무 작 으면 winsock은 자동으로 다른 FD_READ 이벤트를 게시하여 읽을 데이터를 더 많이 알려줍니다. 데이터가 매우 빨리 도착하면 FD_READ 메시지로 메시지 대기열을 포화시킬 수 있으며 WM_TIMER 및 WM_PAINT 메시지는 메시지 대기열이 비어있을 때만 게시되므로 많은 데이터를 수신하고 비동기 너무 작은 버퍼가있는 소켓.

버퍼를 만드는 데 얼마나 큰가요? 나는 바이트 수를 얻기 위해 ioctlsocket (FIONREAD)을 사용하여 시도해 보았고 버퍼를 정확하게 만들었지 만 KB192599 명시 적으로 그 접근법이 비효율적이라고 경고했다.

크고 클 것이 아닌 버퍼 크기를 선택하려면 어떻게해야합니까?

답변

1

내가 해결할 수있는 한 setsockoptSO_RVCBUF 옵션을 사용하여 설정된 값은 FIONREAD 값의 상한값입니다. 따라서 ioctlsocket을 호출하는 대신 getsockopt을 호출하여 SO_RCVBUF 설정을 확인한 다음 각 recv의 (시도한) 값으로 사용하십시오.

Aviad P.의 답변에 대한 귀하의 의견을 토대로이 문제가 해결 될 것 같습니다.

: 곧 돌아 큰 읽기에 대한

+0

나는 가장 현명한 버퍼 크기로 SO_RCVBUF를 사용하려고합니다. –

0

송신자가 더 작은 메시지를 보낸 경우 버퍼를 채우기 전에 TCP PUSH 플래그를 사용하여 읽기를 되돌릴 수 있으므로 성능에 영향을주지 않고 버퍼를 가능한 크게 설정할 수 있습니다.

TCP PUSH 플래그는 논리적 메시지 경계에 설정됩니다 (일반적으로 false로 설정하지 않는 한 send 작업 후). 수신 측에서는 TCP 패킷에서 PUSH 플래그를 볼 때 PUSH 지점까지 수신 버퍼에 축적 된 모든 블로킹 읽기 (또는 비동기 읽기, 중요하지 않음)를 반환합니다.

보낸 사람이 적당한 크기의 메시지를 보내는 경우 사용자가 괜찮 으면 확인한 다음 버퍼 크기를 제한하면 모든 내용을 읽더라도 성능 (주관적)에 부정적인 영향을 미치지 않습니다.

+0

임 걱정하지 (면책 조항. 나는 항상 나 자신하지만 아마 변경됩니다 KB 연결된에 대한 기사를 읽고 ... 후 FIONREAD를 사용했다). 필자의 컨텍스트에서 recv는 FD_READ 이벤트에 대한 응답으로 수행되므로 recv가 차단하려고 시도 할 때마다 즉시 반환 할 것이라고 보장합니다. 내 질문은 어떻게 recv 버퍼를 만들 수 있도록 계산할 수 있도록 하나의 recv 호출에서 보류중인 모든 데이터를 소모 할 수 있습니다. 나는 그것을 1Mb로 만들 수는 있지만, 무어의 법칙은 심지어 오늘날까지도 여전히 미친 자원 낭비 인 반면, 너무 멀지 않은 언젠가는 너무 작지 않을 것이라는 것을 의미합니다. –

+0

그냥 궁금 해서요, 왜 계산해야합니까? 한 번에 하나의 덩어리를 반복 재생할 수 없습니까? –

관련 문제