| James Antill 2007-04-28, 7:04 pm |
| On Fri, 27 Apr 2007 00:50:48 +0000, skaller wrote:
> On Tue, 24 Apr 2007 08:43:35 +0000, Andrei Voropaev wrote:
>
>
> This is what I expected but not what I observed.
>
> In my code I changed between setting and not setting the O_NONBLOCK flag
> and the client read all the data when it was clear, and failed to read
> all the data when it was set.
This proves little, and esp. if you expected differently it'd be much
better to simplify what is being tested as much as possible.
> This was observed using Firefox and wget as the clients. Approximately
> 60K of data is lost in non-blocking mode: which is roughly the buffer
> size Linux uses internally isn't it?
>
> The file being sent is 2.8Meg, the application buffer size is currently
> 100K.
>
> On smaller files there is no observed problem using a local connection.
> For a 1500b/s ADSL connection to a remote server, it failed on every
> file sent.
>
> The 5 second delay fixes it .. there's not much doubt that the buffers
> are not being written by the OS.
There is a huge amount of doubt, why are you assuming that your code is
perfect and wget/firefox are perfect ... but kernel APIs that are used
orders of magnitude more often are behaving differently from how people
are telling you they do?
I've just tested this on kernel-2.6.20-1.2944.fc6 with and-httpd and it
does what I'd expect when contacted via. wget. Ie. The relevant part of
the strace for a request of a 506 byte file is:
accept() = 5
fcntl64(5, F_SETFD, FD_CLOEXEC) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 5, {0, {u32=151302912, u64=151302912}}) = 0
fcntl64(5, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
epoll_ctl(3, EPOLL_CTL_MOD, 5, {EPOLLIN, {u32=151302912, u64=151302912}}) = 0
readv(5) = 99
stat64(fname)
getxattr(fname, "user.mime_type")
open() = 6
fstat64(6)
fadvise64_64(6, 0, 504, POSIX_FADV_SEQUENTIAL) = 0
epoll_ctl(3, EPOLL_CTL_MOD, 5, {0, {u32=151302912, u64=151302912}}) = 0
setsockopt(5, SOL_TCP, TCP_NODELAY, [0], 4) = 0
setsockopt(5, SOL_TCP, TCP_CORK, [1], 4) = 0
readv(6) = 504
close(6)
writev(5) = 782
close(5)
....everything got to the other end fine, I also tried it with a 1,013,075
byte file and it had the same length and md5sum at the other end (the
strace looks roughly the same.
> I hope you are correct. But I can't think what I could possibly be doing
> wrong .. how can i get
>
> close(fd);
>
> wrong?? :)
This is a dis-ingenious argument, esp. given the use of threading.
>
> Originally I didn't. However without it the client seemed to hang about
> waiting for data, and closing the socket at the server end caused
> Firefox to display 'Reset whilst loading file' page, and wget to abort
> and retry the fetch.
wget didn't produce any error messages when I just closed the connection
in my test.
> The HTTP service is deliberately dumb: it doesn't support keep-alive or
> send the file size to the client: the server is basically just a test
> and demonstration of the system's asynchronous I/O capabilities. [For
> fast output, there's no way to know the size of a generated page anyhow:
> you'd have to cache the whole page to find out]
This is one difference from and-httpd, in that it always sends a
Content-Length header ... so it's _possible_ the clients are acting
differently, although that wouldn't be the first place I'd look.
--
James Antill -- james@and.org
http://www.and.org/and-httpd/ -- $2,000 security guarantee
http://www.and.org/vstr/
|