2010-06-16 57 views
1

說我發佈以下WSASend調用(窗口I/O完成端口沒有回調函數):帶有多個緩衝區的WSASend()可能完成不完整?

void send_data() 
{ 
    WSABUF wsaBuff[2]; 
    wsaBuff[0].len = 20; 
    wsaBuff[1].len = 25; 
    WSASend(sock, &wsaBuff[0], 2, ......); 
} 

當我從完成端口的「write_done」通知,是有可能,wsaBuff [1]將被完全發送(25字節),但wsaBuff [0]將只被部分發送(比如說7個字節)?

回答

0

由於WSASend是重疊套接字IO的首選方式,如果它完成而不完整 - 完成通知/例程/事件是應用程序清除/回收使用的結構的唯一方式,則沒有任何意義。

另外:不,這是不可能的,單個WSASend調用仍然是一個IO調用,無論使用什麼緩衝區。

2

正如我之前所說的,在答覆其他一個非常類似的問題時,唯一可能會失敗的時間是資源不足的情況(非頁面緩衝池或鎖定頁面極有可能限制問題),其中您可能會收到ENOBUFS的部分完成和錯誤返回。正如我之前所說的,在10年的IOCP開發工作中,我從來沒有將這看作是生產中的問題,只是在我們一直在對系統進行壓力測試以致死亡的情況下(有時甚至是非分頁游泳池疲憊有時會導致表現不佳的司機藍屏打開箱子)。

我建議你簡單地添加一些代碼來記錄失敗,關閉套接字,就是這樣,你已經處理了失敗的可能性,並可以繼續前進。如果您的失敗處理代碼曾經執行過,我會很驚訝。但是你可以確信你會知道是否是這樣,一旦你可以重現這個問題,你可以花更多的時間思考如果你真的需要更好地處理它。

+0

你確定Len嗎?請注意這個特定的問題 - 這是一個單獨的WSASend()調用,而不是幾個,因此我期望它將WSABUF數組視爲一個單獨的,連續的緩衝區......這就是我的問題。 – Poni 2010-06-17 11:01:15

+0

如果您已將套接字的發送緩衝區大小設置爲零,則您的緩衝區將被鎖定在內存中,並且如果超出鎖定的頁面限制,可能會導致ENOBUFS返回,同樣,我們都不知道確切的非分頁池用法這個情況。事實上,你使用分散/收集I/O不是,恕我直言,實際上是相關的。因爲到WSASend()的文檔並沒有說這種情況不會導致你所問的錯誤,你必須假設它可能發生,因此,恕我直言,我的答案的立場。 – 2010-06-19 09:44:10

相關問題