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

how to use MSG_PEEK flag

2,650 views
Skip to first unread message

zhangyef...@gmail.com

unread,
Dec 2, 2009, 7:06:34 AM12/2/09
to
hi all,
If i want to read N bytes from a socket ,can i do it like this:
1) first ,i call recv with MSG_PEE flag to confirm whether having
N bytes available.
repeat it untill having N bytes available.
2) then, call read once (and just once ) to receive N bytes.

the following is my codes:
/*
return value:
0 : got len bytes in buf successfully
-1: error when receiving data from socket
*/
int myrcv(int fd,int len,char* buf)
{
int n=0;
//peeking whether having n bytes available
while (n <len)
{
n=recv(fd,buf,len,MSG_PEEK);
if(n<len) sleep(1);
}
n=read(fd,buf,len);
if(n!=len)
{
return -1;
}
return 0;
}

are there bugs in my codes ? or anything wrong ?
thank you .


Jorgen Grahn

unread,
Dec 2, 2009, 7:41:30 AM12/2/09
to
On Wed, 2009-12-02, zhangyef...@gmail.com wrote:
> hi all,
> If i want to read N bytes from a socket ,can i do it like this:
> 1) first ,i call recv with MSG_PEE flag to confirm whether having
> N bytes available.
> repeat it untill having N bytes available.
> 2) then, call read once (and just once ) to receive N bytes.
>
> the following is my codes:
> /*
> return value:
> 0 : got len bytes in buf successfully
> -1: error when receiving data from socket
> */
> int myrcv(int fd,int len,char* buf)
> {
> int n=0;
> //peeking whether having n bytes available
> while (n <len)
> {
> n=recv(fd,buf,len,MSG_PEEK);
> if(n<len) sleep(1);

You do not check for errors here.

> }
> n=read(fd,buf,len);
> if(n!=len)
> {
> return -1;
> }
> return 0;
> }
>
> are there bugs in my codes ? or anything wrong ?
> thank you .

Why do you want to use MSG_PEEK? It will not make the code faster;
the sleep() can make it thousands of times slower. If you are going
to sleep, you might as well sleep in a recv() call.

Since you do not want to return until you have len bytes or an error,
why not just call recv() repeatedly, adding to your buf until it is
full? I assume this is a TCP socket in blocking mode.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
buf buf+len
............
read ......
read .......................
read ..
read, and done!

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

zhangyef...@gmail.com

unread,
Dec 2, 2009, 8:16:15 AM12/2/09
to
On Dec 2, 8:41 pm, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
thanks .
the above codes have poor performance ,i know that.
maybe i do not express my true intention .sorry that.
Actually,what i want to know is,whether after peeking having N bytes
available ( that is ,after n=recv(fd,buf,len,MSG_PEEK) , n will be
equal to len ), will the following recv ( called once and just once)
return N bytes (that is ,after n=read(fd,buf,len), n will be equal to
len )?
will this scenario always be true?
thank you

Jorgen Grahn

unread,
Dec 2, 2009, 9:50:49 AM12/2/09
to
On Wed, 2009-12-02, zhangyef...@gmail.com wrote:
...

> maybe i do not express my true intention .sorry that.
> Actually,what i want to know is,whether after peeking having N bytes
> available ( that is ,after n=recv(fd,buf,len,MSG_PEEK) , n will be
> equal to len ), will the following recv ( called once and just once)
> return N bytes (that is ,after n=read(fd,buf,len), n will be equal to
> len )?
> will this scenario always be true?

*That* is a much clearer question. Thanks!

I'm not sure, but one of the experts will probably answer.

I personally do not want to know, because I think using
MSG_PEEK is a sign of a bad design. There is usually a
better way of solving the problem (whatever the problem is).

David Schwartz

unread,
Dec 2, 2009, 10:49:56 AM12/2/09
to
On Dec 2, 4:06 am, "zhangyefei.ye...@gmail.com"

<zhangyefei.ye...@gmail.com> wrote:
> hi all,
>    If i want to read N bytes from a socket  ,can i do it like this:
>    1) first ,i  call recv with MSG_PEE flag to confirm  whether having
> N bytes available.
>        repeat it untill having N bytes available.
>    2)  then, call read once (and just once ) to receive N bytes.

No, you cannot do that. This has to be prohibited because if everyone
did it, nothing would work.

Consider:

Side A has 100 bytes to send side B. But it decide to only send it one
byte. (Heck, why not?)

You peek at the one byte and think "hey, I'll wait for more bytes".
(Heck, why not?)

The other side elects not to send any more data until you accept the
byte it has already sent. (Heck, why not?)

Deadlock.

So there are two ways to solve this:

1) You could have a rule that the sender can never refuse to send data
just because the other side has not completed receiving data. But this
is a disaster as it requires unlimited in flight data.

2) You could have a rule that a receiver can never refuse to read/
accept data just because the other side has not completed sending
data. This is not a disaster, so this is the rule we have.

You are asking "can I violate this rule". The answer is, no, because
if everyone violated all the rules, nothing would work. You will
likely get away with it, because everyone else is probably following
the rules.

It's kind of like not paying taxes. You won't bankrupt the government
so long as everyone else pays taxes. But officially, it must be
prohibited because if everyone did it, nothing would work.

DS

Philip Paeps

unread,
Dec 2, 2009, 6:47:29 PM12/2/09
to
David Schwartz <dav...@webmaster.com> wrote:
> No, you cannot do that. This has to be prohibited because if everyone
> did it, nothing would work.

[...]

> It's kind of like not paying taxes. You won't bankrupt the government
> so long as everyone else pays taxes. But officially, it must be
> prohibited because if everyone did it, nothing would work.

That is an *excellent* metaphor to explain why "playing by the rules" is
important. Expect to be quoted frequently!

Many thanks.

- Philip

--
Philip Paeps Please don't email any replies
phi...@paeps.cx I follow the newsgroup.

"You see a wile, you thwart. Am I right?"
-- Crowley the demon and Aziraphale the angel in conversation
(Terry Pratchett & Neil Gaiman, Good Omens)

0 new messages