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

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 a way to determine how many bytes can be sent?

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

FIONWRITE is not available for Winsock.

+4
source share
2 answers

According to Alexander Nikolaevich MVP , there is no such tool in Windows. He also mentions that β€œgood socket code” does not use FIONWRITE-like ioctls, but does not explain why.

To work around this problem, you can enable non-blocking I / O (using FIONBIO , I think) on sockets. In this case, WSASend will succeed on such sockets when it can complete sending without blocking, or fail with WSAGetLastError() == WSAEWOULDBLOCK , when the buffer is full (as indicated in the documentation for WSASend ):

WSAEWOULDBLOCK

Hidden Sockets: Too many outstanding I / O requests overlap. Non-overlapping sockets: The socket is marked as non-blocking, and the send operation cannot be performed immediately.

Also read additional notes about this error code .

+3
source

Winsock send () blocks only if the socket is in blocking mode and the outgoing socket buffer is filled with data in the queue. If you control multiple sockets in the same thread, do not use blocking mode. If one receiver does not read data during timely changes, this can lead to damage to all connections in this stream. Instead, use non-blocking mode, then send () will tell you when the socket has entered a state in which blocking will occur, then you can use select () to detect when the socket will again be able to receive new data. The best option is to use overlapped I / O or I / O ports. Send outgoing data to the OS and let the OS handle all the expectations, notifying you when the data was ultimately received / sent. Do not send new data for this socket until you receive this notification. To provide scalability for a large number of connections, I / O completion ports are generally the best choice.

0
source

Source: https://habr.com/ru/post/1439369/


All Articles