2012-10-12 34 views
4

使用select可以確定是否有任何字節可以被接收或發送而沒有阻塞。確定可以使用winsock(FIONWRITE)發送多少個字節?

有了這個功能,我能確定有多少字節可接收:

function BytesAvailable(S: TSocket): Integer; 
begin 
    if ioctlsocket(S, FIONREAD, Result) = SOCKET_ERROR then 
    Result := -1; 
end; 

有也是一種方式,以確定有多少字節可以發送?因此我可以確定當我使用N個字節發送數據時,它將返回恰好N個字節(或SOCKET_ERROR)但不少於(發送緩衝區已滿)。

FIONWRITE不適用於Winsock。

+0

我讀過幾篇指南,指出「嚴重的應用程序使用非阻塞IO」,因爲文檔模糊不清,阻塞行爲和可移植性差,即使文檔存在。 – Gene

回答

3

According to MVP Alexander Nickolov,在Windows中沒有這樣的設施。他還提到「良好的套接字代碼」不使用FIONWRITE類似的ioctls,但不能解釋原因。

要對你有興趣,只有這樣,WSASend將這種插座成功時,它可以完成發送,而不阻止套接字繞過這個問題,你可以啓用非阻塞I/O(使用FIONBIO,我猜)或失敗,WSAGetLastError() == WSAEWOULDBLOCK當緩衝區已滿(如documentation for WSASend說明):

WSAEWOULDBLOCK

重疊插座:有太多優秀的重疊I/O請求。非重疊套接字:套接字被標記爲非阻塞,並且發送操作不能立即完成。

也讀出further notes about this error code

0

只有套接字在阻塞模式下運行並且套接字的出站緩衝區填滿了排隊數據時,Winsock send()纔會阻塞。如果您在同一個線程中管理多個套接字,請不要使用阻塞模式。如果一個接收者不及時讀取數據,它可能會導致該線程上的所有連接都受到影響。相反,使用非阻塞模式,那麼send()將報告套接字何時進入阻塞狀態,然後您可以使用select()來檢測套接字何時可以再次接受新數據。更好的選擇是使用重疊的I/O或I/O完成端口。將出站數據提交給操作系統,讓操作系統處理所有等待您的數據,並在數據最終被接受/發送時通知您。在收到該通知之前,不要爲給定套接字提交新數據。對於大量連接的可擴展性,I/O完成端口通常是更好的選擇。