2009-12-30 53 views
0

我有一個使用WSAASyncSelect將套接字置於異步模式的套接字庫的問題。在異步模式下,套接字被置於非阻塞模式(在阻塞的任何操作上返回WSAWOULDBLOCK),並且將窗口消息發佈到通知窗口,以通知應用程序套接字何時可以被讀取,寫入等。從異步套接字讀取數據最佳

我的問題是這樣的 - 接收FD_READ事件,我不知道有多少字節的嘗試和recv時。如果我傳遞的緩衝區太小,那麼winsock會自動發佈另一個FD_READ事件,告訴我更多要讀取的數據。如果數據以非常快的速度到達,可以使用FD_READ消息使消息隊列飽和,並且由於只有當消息隊列爲空時纔會發送WM_TIMER和WM_PAINT消息,這意味着如果應用程序接收到大量數據並使用異步緩衝區太小的套接字。

然後製作緩衝區有多大?我嘗試使用ioctlsocket(FIONREAD)來獲取要讀取的字節數,並製作一個完全相同的緩衝區,但是,KB192599明確警告說,這種方法充滿效率低下。

如何挑選足夠大的緩衝區大小,但不是瘋狂的大?

回答

1

就我所能解決的問題而言,使用setsockoptSO_RVCBUF選項設置的值是FIONREAD值的上限。因此,而不是調用ioctlsocket應該OK打電話getsockopt找出SO_RCVBUF設置,並使用爲每個recv的(未遂)值。

基於對阿維亞德P.的回答您的意見,這聽起來像這將解決您的問題。

(聲明:我一直用自己FIONREAD但閱讀鏈接到的知識庫文章,我可能會被改變......之後)。

+0

我會用SO_RCVBUF作爲最明智的緩衝區大小來使用。 – 2010-01-03 11:08:43

0

您可以設置緩衝區是一樣大的,你可以在不影響性能,依靠TCP PUSH標誌,使您的閱讀填充緩衝區,如果發送方發送一個小的消息之前的回報。

的TCP PUSH標誌被設置爲邏輯消息邊界(發送操作後,通常,除非明確地設置爲false)。當接收端在TCP數據包上看到PUSH標誌時,它將返回任何阻塞讀取(或異步讀取,無關緊要),直到PUSH點爲止,在接收緩衝區中累積的任何內容。因此,如果你的發件人發送的是合理大小的信息,那麼你可以,如果他不是,那麼你限制了你的緩衝區大小,這樣即使你全部讀完了,你也不會對性能(主觀)產生負面影響。

+0

我不是擔心大的讀回很快。在我的上下文中,我正在執行recv以響應FD_READ事件,所以它保證recv將立即返回一些信息,而不會立即嘗試阻止它。我的問題是,如何計算recv緩衝區的大小,以便在一次recv調用中排除所有待處理數據。我可以做到1Mb,但摩爾定律暗示,即使這樣做可能會有一天不會太遠,但仍然是今天瘋狂浪費資源。 – 2009-12-31 14:06:36

+0

只是好奇,你爲什麼要計算它?你不能一次循環一次嗎? – 2009-12-31 14:33:14