[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: flawed LuaSocket select()/tcp.receive() interaction ?
- From: lua@...
- Date: Mon, 20 Nov 2006 19:22:13 +0100
* On 2006-11-20 Diego Nehab <diego@tecgraf.puc-rio.br> wrote :
> First, here is a good start
>
> http://www.catb.org/~esr/faqs/smart-questions.html
Yes, I know that page - can you please specify what was not clear about
my question, this will surely help me ask smarter ones next time.
> >Assume I call tcp.receive() with lenght '8', and
> >
> >- Fewer then 8 bytes come in. tcp.receive() does not return, and
> >blocks until more data arrives. This is not acceptable for me: I
> >should be able to read all available data when select() indicates
> >something's there, and continue right away.
>
> This is also the behavior of the C version of recv on blocking
> sockets. To get a different behavior, you must put the socket in
> non-blocking mode.
No, I'm afraid this is not the case. From the linux man page of recv:
"The receive calls normally return any data available, up to the
requested amount, rather than waiting for receipt of the full amount
requested."
This is the exact behaviour I'd expect from recv(), and also the exact
behaviour I depend on in my C programs. This is an important difference
between lua socket receive and recv. When select marks a socket as
readable, recv() is guaranteed not to block.
> >- more then 8 bytes of data come in. tcp.receive() does not pass my
> >length argument to the libc receive() function, but reads a whole
> >buffer at a time (8192 bytes, in my case). tcp.receive() only returns
> >the first 8 bytes, as requested. The rest of the data was already
> >reveied and is stored somewhere by luasocket in a buffer.
>
> Also in C, the fact you pass 8 to recv() doesn't mean the data isn't
> waiting for you in an OS buffer. In fact, it probably is. All
> LuaSocket does is add an extra layer of buffering there, so that
> reading line patters becomes viable.
No, this is not the case in with the libc recv(). If fewer bytes are
recv()'d from a TCP socket then available, only the requested amount of
bytes are returned, and the rest will be pending for the next recv().
select() will still indicate the socket is ready for reading in this
case.
> >So, what do I need to do to handle this properly ? Is there a way to
> >make tcp.receive() have the same behaviour as my libc's receive(),
> >that is - don't receive any more then the requested amount of bytes
> >from the socket, and leave the rest pending so select() will notice
> >there's still data waiting to be read.
>
> Yes, it will. There is code there to specifically handle this case. If
> you have a sample that doesn't work, this is a bug and it must be
> fixed. Are you just assuming that it doesn't work?
No, I tested. If it is of any help I can could make some minimal
examples in both C and Lua to show the different behaviour
> >- also return when fewer then the requested amount of bytes are
> >received, returning both the data and it's size
>
> This is not the standard behavior in C either. You have to put the
> socket in non-blocking mode. To do that in LuaSocket, simply set the
> timeout to 0.
Nonblocking mode should never be necassery when using select(),
because of the proper behaviour of recv() as I described above.
--
:wq
^X^Cy^K^X^C^C^C^C