确定有多少字节可以用winsock的(FIONWRITE)发送?(Determine how man

2019-08-01 10:04发布

与选择我可以确定是否有任何字节可以被接收到的或不阻塞发送。

有了这个功能,我能确定有多少字节可接收:

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

有没有也是一种方式,以确定有多少字节可以发送?

所以,我可以肯定,当我打电话与N个字节的发送,它将返回确切的N发送字节(或SOCKET_ERROR),但不小于(发送缓冲区已满)。

FIONWRITE不适用于Winsock的。

Answer 1:

据MVP亚历山大Nickolov ,有是Windows没有这样的设施。 他还提到,“好插座码”不使用FIONWRITE般的读写控制,但并没有解释为什么。

为了规避这个问题,你可以启用非阻塞I / O(使用FIONBIO对你感兴趣的插座,我猜)。这样一来, WSASend将这种插座成功时,它可以完成发送,而不阻塞,或失败, WSAGetLastError() == WSAEWOULDBLOCK当缓冲器满(如中注明为文档WSASend ):

WSAEWOULDBLOCK

重叠插座:有太多优秀的重叠I / O请求。 不重叠的套接字:套接字被标记为非阻塞和发送操作不能立即完成。

还可以阅读有关此错误代码进一步指出 。



Answer 2:

Winsock发送()只如果套接字在阻断模式下运行并且所述插座的出站缓冲器与排队的数据填满块。 如果你是在同一个线程管理多个插座,不要使用阻塞模式。 如果一个接收器没有及时满耳读取数据,这可能会导致所有在该线程的连接受到影响。 使用非阻塞模式,而不是,然后发送()会报告在套接字进入其中阻塞会发生的状态,那么你可以使用select()来检测时,插座可以重新接受新的数据。 更好的选择是使用重叠I / O或I / O完成端口来代替。 提交出站数据到操作系统,让操作系统处理所有的等着你,通知您当数据最终被接受/发送。 直到收到该通知,不要对一个给定的插座提交新的数据。 在可扩展性,以大量的连接,I / O完成端口通常是更好的选择。



文章来源: Determine how many bytes can be sent with winsock (FIONWRITE)?