Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RECV all data in receive buffer

464 views
Skip to first unread message

Martin Stich

unread,
Apr 25, 2004, 2:31:50 AM4/25/04
to
hi
i simply want to recv all data that is currently in the input buffer
(with a non-blocking socket if possible).
however, i've read that using select to check if there's data available
and if yes, ready byte-by-byte until there's no more is inefficient
(which i readily believe ;).
i've also read that calling recv with MSG_PEEK or ioctlsocket with
FIONREAD to check the amount of data pending is broken -
see http://support.microsoft.com/support/kb/articles/Q192/5/99.ASP
so what method should i use ?
thanks


Martin Stich

unread,
Apr 25, 2004, 2:54:26 AM4/25/04
to

sorry, what i meant was: the socket i have is a _blocking_ socket,
but i want to read all the available data while being sure that the
operation won't block.

"Martin Stich" <n...@spam.com> schrieb im Newsbeitrag
news:c6fm1g$jru$01$1...@news.t-online.com...

Peter Duniho

unread,
Apr 25, 2004, 3:17:02 AM4/25/04
to
"Martin Stich" <n...@spam.com> wrote in message
news:c6fnbt$gnc$02$1...@news.t-online.com...

>
> sorry, what i meant was: the socket i have is a _blocking_ socket,
> but i want to read all the available data while being sure that the
> operation won't block.

If you don't want a socket to block, you need to use non-blocking sockets.
Forget trying to anticipate how many bytes you think you can read. Besides,
when reading, as long as there's even one byte, the call to recv() won't
block. You don't need to know the actual number of bytes waiting.

As for whether you can "recv all data that is currently in the input
buffer", forget that too. The instant you complete a read operation on your
socket, some more data could come in. There is no way for you to ensure
that you have read all available data, and there's no good reason for you to
want to do so in the first place (even assuming there was an API that let
you know the absolute total number of bytes that have arrived at your
computer and are ready to be read, which there isn't).

By the way, if you read the KB article to which you posted the link, you
would see that it's not that MSG_PEEK/FIONREAD is broken, but rather that
code that uses either generally is broken.

Pete


David Schwartz

unread,
Apr 26, 2004, 4:05:01 PM4/26/04
to

"Martin Stich" <n...@spam.com> wrote in message
news:c6fnbt$gnc$02$1...@news.t-online.com...

> sorry, what i meant was: the socket i have is a _blocking_ socket,


> but i want to read all the available data while being sure that the
> operation won't block.

If you don't want to block, what are you doing with a blocking socket?
How do you know there's any data there at all?

DS


Phil Frisbie, Jr.

unread,
Apr 26, 2004, 6:23:40 PM4/26/04
to

I agree that code that relies upon MSG_PEEK/FIONREAD is generally broken, and is
most often written by programmers that do not fully understand TCP streams or
blocking sockets. However, I think FIONREAD is broken in Microsoft's code
because instead of reading an internal state counter it copies the data just
like MSG_PEEK.

Also, recv() is not even guaranteed to return all data that is currently
buffered for a TCP socket. Looping on recv() is the only way to get all buffered
data.

> Pete


--
Phil Frisbie, Jr.
Hawk Software
http://www.hawksoft.com

Alun Jones [MS MVP]

unread,
Apr 27, 2004, 8:14:43 AM4/27/04
to
In article <108mpfr...@corp.supernews.com>, "Peter Duniho"
<NpOeS...@NnOwSlPiAnMk.com> wrote:
>By the way, if you read the KB article to which you posted the link, you
>would see that it's not that MSG_PEEK/FIONREAD is broken, but rather that
>code that uses either generally is broken.

I'll underline this, and make the following notes:
1. Blocking sockets are generally best-used for writing small sample code to
demonstrate something relatively simple. It doesn't take long before you
chafe against the fact that your program will stop until network traffic
arrives, and at that point, you know that you should be using non-blocking
sockets. You know that's what you should be doing, and yet you feel
comfortable and safe in the warm embrace of the blocking socket. Come to
the light, leave the safety of the blocking socket, and embrace the power of
the non-blocking!

2. MSG_PEEK is generally a bad idea, because it gives you data without
freeing up buffer space, and you'll have to go back and read that data later
anyway.

3. FIONREAD is definitely a bad idea. At best, it takes a fair amount of
time and is unnecessary. At worst, it takes the same amount of time as
actually reading the data (consider, for instance, a service provider that
compresses and decompresses the data stream - to tell you how many bytes are
there, it would have to decompress the whole stream before returning).

3.1 FIONREAD isn't necessary. What will you do with the value returned?
Create a buffer of that size? Bad move. Use a buffer that you keep in
memory, so your code isn't continually removing and adding memory
allocations (which will slow you down). Ask to read in as much as you can
handle, and handle as much as you are given. You will encounter situations
when you need to hold onto that data for the next time data comes in.

3.2 FIONREAD is inaccurate. Implementation in at least one version of the
TCP/IP stack meant that it would only return up to 8kB, no matter how much
was waiting for you. Also, more data may arrive in between the return from
ioctlsocket, and you calling recv. Just ask to read as much as you can
handle, and handle as much as you get.

3.3 FIONREAD is unused. The rest of the network development community
rarely use FIONREAD. As such, guess where it goes in the list of "things to
test, fix and get right"? Way down at the bottom. Rely on it, and you'll
find that if it breaks, your code will stop working right, and will have to
wait until it becomes important enough to fix. This will make your code
seem fragile.

Alun.
~~~~

[Please don't email posters, if a Usenet response is appropriate.]
--
Texas Imperial Software | Find us at http://www.wftpd.com or email
1602 Harvest Moon Place | al...@texis.com.
Cedar Park TX 78613-1419 | WFTPD, WFTPD Pro are Windows FTP servers.
Fax/Voice +1(512)258-9858 | Try our NEW client software, WFTPD Explorer.

Alun Jones [MS MVP]

unread,
Apr 27, 2004, 10:41:43 AM4/27/04
to
In article <MZfjc.8252$Fo4.1...@typhoon.sonic.net>, "Phil Frisbie, Jr."
<ph...@hawksoft.com> wrote:
>I agree that code that relies upon MSG_PEEK/FIONREAD is generally broken, and
> is
>most often written by programmers that do not fully understand TCP streams or
>blocking sockets. However, I think FIONREAD is broken in Microsoft's code
>because instead of reading an internal state counter it copies the data just
>like MSG_PEEK.

If it didn't, how would it cope with an LSP that compresses and uncompresses
data?

>Also, recv() is not even guaranteed to return all data that is currently
>buffered for a TCP socket. Looping on recv() is the only way to get all
> buffered
>data.

Generally, it's more appropriate to call recv() once for every FD_READ
notice you get. Looping on recv() generates extraneous FD_READ notices.

0 new messages