Monday, October 11, 2004

TransmitFile

<Technobabble>
The TransmitFile API is friggin' cool!

Well.. it's pretty cool, but not developed enough, in my opinion. It's a great idea because efficiency goes up significantly - it saves at least two buffer copies, one ReadFile and one send. Also, it uses the standard asynchronous I/O mechanism (the OVERLAPPED structure) and, knowing that SOCKETs are in fact HANDLEs under cloak, you can use the standard wait functions on the handle returned by socket.

One of its problems, however, is that there's no way (that I know of) to query the progress of a TransmitFile (in fact, is there a way to generally query the progress of an asynchronous I/O operation?). The OVERLAPPED structure does not change until the end of the operation, which is why GetOverlappedResult is useless.
Attempting to retrieve the file pointer during the operation constantly returns a position of 4096 bytes into the file (why 4096, I don't know).
Is there some ioctl or socket option to query the number of bytes sent on a given socket?
Either way, there must be some file pointer somewhere in AFD.SYS (this is the driver that carries out the actual operation)!

I've conceived a hack for this, however. Instead of sending the entire file in one call, I use many calls that send "quantas". In the application, I dynamically adjust the quanta size to obtain roughly 500 ms per quanta (this allows for a reasonable refresh rate of the interface). Also, I found it prudent to provide "sanity checks" for the quanta size. My lower limit is 4096 bytes, while the upper limit is 262144 (256K) bytes.
</Technobabble>

No comments: