Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

problem with fcopy

Status
Not open for further replies.

spa321

Technical User
Sep 26, 2007
3
US
hi all,
I'm having a problem using fcopy. I'm just reusing code that has been working fine for transfer .pgm and .zip files for a long time. For this 2 ext, although they are binary files I use -translation lf.
Now, I need to transfer an executable (7za.exe -from the 7z GNU project-). The file doesn't transfer properly (get corrupted and doesn't execute). I tried with -translation binary; and combinations of lf and crlf according to the 'in' and 'out' for each side, with no luck (although I can see the size of the file transferred change, the size sent by the server is always the same and identical to the size of the file storage in teh server)

below is the working code for .pgm and .zip files.
I'd appreciate any help, either to make it work or another way of transfering the file automatically if needed by the client

thanks,
Sergio


on the client side (OS: W2K)

if { ![ file exists $unzipper ] } {
set serverpath $config(raw)/7za.exe
set out [open $unzipper w+]
ClientSend sendfile $serverpath ; #send the command to the server
set in $config(server)
fconfigure $in -translation lf
fconfigure $out -translation lf
fcopy $in $out
close $in
close $out
}
####################################
on the server side (OS: Unix)

proc SendFile { filename } {
global server
global total
set in [open $filename]
set out $server(client)
fconfigure $in -translation lf
fconfigure $out -translation lf
fcopy $in $out -command [list CleanPort $in $out]
vwait total
return
}
proc CleanPort { in out bytes { error {} } } {
global total
set total $bytes
close $in
close $out
puts "Transferred $total"
if {[string length $error] != 0 } {
puts "CleanPort fcopy error $error"
}
return
}
 
It isn't shown in your code but I assume the initialization of config(i) is working ok?

It shouldn't make any difference but just to check, try changing the name of the .exe file to .<something else> and see if that works. .exe's sometimes do funny things.

Also, try putting a -command <callback> on the client side fcopy to see if you can capture an error.

_________________
Bob Rashkin
 
the initialization (config(server)) works fine: the program first download a zip file from the server, then check if exists the unzipper before downloaded it. The zip file is downladed fine, and all the interactions server-client after the download are fine.

I tried with another ext, it didn't work. Also, i put the callback on the client side and didn't get any error.

any other suggestion?

thanks for your help
Sergio
 
That's peculiar then. I think it must be related to the size and the send/receive is out of synch between the client and server. Otherwise, why would .zip work? See what happens with small vs big files of any name.

_________________
Bob Rashkin
 
hi Bob,
now you get me worried. This program launches tomorrow, what I did is: if the 7za.exe doesn't exists, then launch IE and ask the user to download it (this should be done only once, so not a big problem).

But, if your suggestion that the problem may be linked to the size of the file is true, then I'm dead. During the testing the zip file is much smaller than the 7za.exe but, on real life the zip file depending on the day, most likely will be much bigger.

let me tell you what i found so far:
i used od -c to check the binary files:
- using translation lf and binary, there is no difference between the files
- the original file is smaller (11 bytes) than the transferred file
- i can't make much sense of the ascci translation of the binary files, but i noticed that the transferred files contain in the first line the words 'data done', it also have other lines added in the middle of the file.

Before continuing, let's take a look at the workflow:
- login, password, etc
- download the zip file. When the transfer is complete, the server puts 'data done' into the client
- when client receive 'data done', check if the unzipper exists, and precede to unzip the file
- etc...

i was thinking on some kind of buffer problem, although i don't quite get it: 'data done' was already sent, (otherwise it wouldn't ask for the unzipper), so why it is showing again?, and where are the other extra lines coming from?

i'm thinking on putting a flush command before closing $in and $out in the CleanPort proc; and also put a flush command
after a puts into the client.

you mention that the send/receive between the client and server may be out of sync. How can this be possible, how can i check it, and most important, how do i fix it?

thanks for your time and help
Sergio
 
First, I'd try testing with various sizes of files to see if, indeed, size matters. Then, I'd play around with fblocked on a file that exhibits the problem to see if the channel is being blocked:
help said:
SYNOPSIS
fblocked channelId


DESCRIPTION
The fblocked command returns 1 if the most recent input operation on channelId returned less information than requested because all available input was exhausted. For example, if gets is invoked when there are only three characters available for input and no end-of-line sequence, gets returns an empty string and a subsequent call to fblocked will return 1.

ChannelId must be an identifier for an open channel such as a Tcl standard channel (stdin, stdout, or stderr), the return value from an invocation of open or socket, or the result of a channel creation command provided by a Tcl extension.
flush is a good idea, too.

The fact that the transfered file is larger than the original troubles me. Try -translation binary to see if that changes things. They should be the same size.

_________________
Bob Rashkin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top