> Hello ICS Mailinglist,

> this is a bugreport that on localhost the windows kernel reads megabytes 
> of data
> before a TWSocket client can block. As you can see on the following 
> explanation
> and the images on

> http://projekte.priv.de/ics_localhost_bug/

> , the problem is the windows kernel:

The problem is that you don't understand how ICS work.
By this:

transfered := socket.Send(@buf, sizeof(buf)); 


buf: array[0..102400] of byte;

you command ICS TWsocket to send 102401 bytes. It doesn't necessarily mean
that it goes straight to Windows Sockets (or TCP/IP stack, whatever).
Now, in TWSocket.Send, component splits your data (these 102401 bytes) into
~1,5 kilobyte chunks, puts every chunk into FIFO (first-in-first-out)
queue, enlarging it, then sends every chunk one-by-one, shrinking the queue.
Component sends data to TCP/IP stack as long as this doesn't err out (ie.
send() doesn't return error "Operation would block" - or any other error - 
what may happen when, for example, destination socket doesn't consume sent
data). When you do .pause on receiving (*NOT* sending) socket, you say "ok,
now I don't want to know that new data have arrived".  Meanwhile, sending 
TWSocket component *still* send data to TCP/IP on his side, TCP/IP sends
data to destination socket, TCP/IP on the destination side sees that socket
doesn't consume data so it buffers them as long as there's enough space for
this (see SO_RCVBUF), and when buffer is full, it responds to sending side
with some kind of "sorry, i cannot handle more data, you're talking too
fast". Sending socket, seeing this, responds to queue pumping code (within
TWSocket) with "Operation Would Block", what makes FIFO in TWSocket stop
shrinking. That's why memory usage of sending application skyrockets:
receiving side doesn't receive data (because it doesn't want to know that
data have arrived), and sending side is not aware of this.

Why? Because you just say "send! send! send! send it goddamnit! send it!!!"
not checking whether something has actually been sent *and* received.
You have OnDataSent for this purpose - it's fired when TWSocket sending
FIFO queue is emptied successfully.

To cut things short - by using TWSocket's "send" method, you say "put these
data in your buffers, send it to the other side, and tell me, by firing
OnDataSent, when you've dealt with that.". If you use "send" again - before
having received OnDataSent event - you say "hey, I have some more data to
send, send them when you'll deal with all previous data, and tell me, by
firing OnDataSent, when you'll send *all* data - the previously ordered to
send *and* the new data."


Piotr Dałek

Kochanka - kobieta drugiej kategorii?
sprawdz >>>http://link.interia.pl/f2026

To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to