For Programmers: Free Programming Magazines  


Home > Archive > Tcl > March 2008 > serving a file to a client --- background fcopy read fileevent event









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author serving a file to a client --- background fcopy read fileevent event
vitick@gmail.com

2008-03-28, 7:30 pm

After spending a lot of time trying to do a nonblocking transfer of a
large file with fcopy, I gave up on fcopy. I did come up with a
solution that is working nicely for me and simulates fcopy. Hopefully
my experience will help others since many have the same problems. May
be someone will suggest a better solution or improve on the idea.

First, some background on my experience with event driven programming
in TCL:

Event driven programming is not clearly documented. For example, if
you try to do something like this:

-----------------------------------------------------------------------------------------------------------------------------------------------------

#start of the code here
#more code

while {1} {#do something here; after 1000} #want to serve other
events, like sending a file to a socket

# since we have "vwait forever" (below) in our code

# you would think that this while loop will not block

#but it blocks anyway, not , that's not what documentation

#that I read implies.
vwait forever

-----------------------------------------------------------------------------------------------------------------------------------------------------
Here is how to make it work:
-----------------------------------------------------------------------------------------------------------------------------------------------------

#start of the code here
#more code

while {1} {#do something here; after 1000 [list set myvariable];
vwait myvariable}

vwait forever

-----------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------

Ok, now about transferring a large file without blocking all other
events:

The code:
-----------------------------------------------------------------------------------------------------------------------------------------------------
set fp [open /myfile]
#the socket $sock is already open by "socket -server"
set size 1024
set after_time 10

fconfigure $fp -translation binary -encoding binary -buffersize
$size -buffering full -blocking 0
fconfigure $sock -translation binary -encoding binary -buffersize
$size -buffering full -blocking 0

proc send_file {fp sock size after_time} {
while { ![eof $fp] && ![eof $sock] } {

puts -nonewline $sock [read $fp $size]
after $after_time [list set wait_var]
vwait wait_var
}
flush $sock #flush the remaining unsent data to the client
s $fp 0 start # rewind the file pointer back to the beginning of
the file for the next transfer
}
-----------------------------------------------------------------------------------------------------------------------------------------------------

This assumes that you have a main "vwait forever" code in your script
to for all other events.
If you experiment with the values of the above variables "size and
after_time" you will have a very effective control of the speed of the
transfer (throttling) and the time set aside for other events.
NOTE: you cannot have more than one transfer of the same file using
the same file pointer at the same time. You need to open another file
pointer to the same file for each transfer request that happens while
another transfer is in progress.

----Victor





Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com