I just looked at the socket code, the main part being in nsd/sock.c:
---
Ns_SockSend(SOCKET sock, void *buf, int towrite, int timeout)
{
int nwrote;
nwrote = send(sock, buf, towrite, 0);
if (nwrote == -1
&& ns_sockerrno == EWOULDBLOCK
&& Ns_SockWait(sock, NS_SOCK_WRITE, timeout) == NS_OK) {
nwrote = send(sock, buf, towrite, 0);
}
return nwrote;
---
Ns_SockWait(SOCKET sock, int what, int timeout)
{
fd_set set;
struct timeval tv;
int n;
if (timeout < 0) {
return NS_TIMEOUT;
}
do {
FD_ZERO(&set);
FD_SET(sock, &set);
tv.tv_sec = timeout;
tv.tv_usec = 0;
switch (what) {
case NS_SOCK_READ:
n = select(sock+1, &set, NULL, NULL, &tv);
break;
case NS_SOCK_WRITE:
n = select(sock+1, NULL, &set, NULL, &tv);
...
---
I think it would be very hard to impossible to block until all the
data has been received by a client browser, because that only happens
at close time. Actually, data transmission from the server occurs
even after the server closes the socket.
The code above says:
- try to write up to "towrite" bytes
- if you wrote anything at all, return the number written
- if you couldn't write any because the socket buffer is full, wait
until there is at least 1 byte available in the socket buffer (impl. dep)
- write however many bytes you can and return the number written.
It seems to me this should be in a loop, but maybe no one else has
access to the socket and so it's no possible for the socket state to
change after the select and before the second write.
If your socket buffer is 4K for example, you could still write a 1MB
message. You would be stuck in select most of the time. As packets
leave, the socket buffer gets more space and more data can be sent
to it.
My interpretation anyway...
Jim
>
> I'm using AOLserer 3.3+ad13 on Solaris 8.
>
> In the past I've been told that ns_write will block until all the data
> has been received by the client browser. So, if the client is on a
> paricularly slow connection, ns_write could block for a long time.
>
> Is that really true? Or is it just that ns_write will block if the
> socket send buffer is full? And if so, how do I find out how big my
> TCP/IP send buffer is?
>
> I have an application where I'm generating poetentially a whole lot of
> data, which can be relatively slow, and where the client can start
> making use of the data even before all of it is received. So, it sure
> would be nice to ns_write out the data in chunks as we generate it,
> rather than waiting and ns_return'ing the whole thing at the end.
>
> But, is ns_write's underlying implementation using the TCP/IP socket
> send buffer intelligently, or does it force a send of a separate
> packet for every single call to ns_write? Even if, e.g., the socket
> send buffer is large and we call ns_write with only 1 byte of data?
>
> What steps do you recomend taking in order to limit the performance
> impact of using ns_write, while still being able to stream out results
> as you generate them?
>
> Thanks!
>
> --
> Andrew Piskorski <[EMAIL PROTECTED]>
> http://www.piskorski.com
>