Re: serving a file to a client --- background fcopy read fileevent event puts socket channel blocking nonblocking
- From: vitick@xxxxxxxxx
- Date: Fri, 28 Mar 2008 13:55:27 -0700 (PDT)
On Mar 28, 12:50 pm, Bruce Hartweg <bruce-n...@xxxxxxxxxx> wrote:
vit...@xxxxxxxxx wrote:
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.
can I ask a few questions? I;m not sure of what problems you had with fcopy
and would like more info. were you using the -command version of it?
how was it being called? what was the negative effects?
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:
hmmm, i find it pretty well documented. could you explain what you
found lacking in detail
-----------------------------------------------------------------------------------------------------------------------------------------------------
#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 cool, that's not what documentation
#that I read implies.
what documentation did you read that made you think
while {1} {
# do stuff
after 1000
}
would have any way of processing events?
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
very kludgy - why are you going this route instead of doing
your processing in an event, intead of an infinite loop?
-----------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------
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
seek $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
this may solve your problem, but your problem may have been the structure of your
code in the first place. i don;t see anything here that couldn't be done
with fcopy and the -command and -size options
Bruce
Well, it turns out that it doesn't work for more that one instance of
the loop code.
I was trying to do several things -- speed control of the transfer,
progress notification and backgrounding long running procs (the
infinite while loop was just an example).
Back to reality again.
Thanks
.
- Follow-Ups:
- References:
- Prev by Date: Re: serving a file to a client --- background fcopy read fileevent event puts socket channel blocking nonblocking
- Next by Date: Re: Autoexpect under Windows (and later Mac and Linux)
- Previous by thread: Re: serving a file to a client --- background fcopy read fileevent event puts socket channel blocking nonblocking
- Next by thread: Re: serving a file to a client --- background fcopy read fileevent event puts socket channel blocking nonblocking
- Index(es):
Relevant Pages
|