Determine how many bytes can be sent with winsock (FIONWRITE)?

风格不统一 提交于 2019-12-21 05:31:45

问题


With select I can determine if any bytes can be received or sent without blocking.

With this function I can determine how many bytes can be received:

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

Is there also a way to determine how many bytes can be sent?

So I can be sure when I call send with N bytes, it will return exactly N bytes sent (or SOCKET_ERROR) but not less (send buffer is full).

FIONWRITE is not available for Winsock.


回答1:


According to MVP Alexander Nickolov, there is no such facility in Windows. He also mentions that "good socket code" doesn't use FIONWRITE-like ioctls, but doesn't explain why.

To circumvent this issue, you could enable non-blocking I/O (using FIONBIO, I guess) on sockets you're interested in. That way, WSASend will succeed on such sockets when it can complete sending without blocking, or fail with WSAGetLastError() == WSAEWOULDBLOCK when the buffer is full (as stated in the documentation for WSASend):

WSAEWOULDBLOCK

Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as nonblocking and the send operation cannot be completed immediately.

Also read further notes about this error code.




回答2:


Winsock send() blocks only if the socket is running in blocking mode and the socket's outbound buffer fills up with queued data. If you are managing multiple sockets in the same thread, do not use blocking mode. If one receiver does not read data in a timely maner, it can cause all of the connections on that thread to be affected. Use non-blocking mode instead, then send() will report when a socket has entered a state where blocking would occur, then you can use select() to detect when the socket can accept new data again. A better option is to use overlapped I/O or I/O Completion Ports instead. Submit outbound data to the OS and let the OS handle all of the waiting for you, notifying you when the data has eventually been accepted/sent. Do not submit new data for a given socket until you receive that notification. For scalability to a large number of connections, I/O Completion Ports are generally a better choice.



来源:https://stackoverflow.com/questions/12858259/determine-how-many-bytes-can-be-sent-with-winsock-fionwrite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!