From: Y.T. on
Someone else already noted that we might need more than just the procs
-- where and when are the sockets even opened? And now?

Does everything work if you run the sender and receiver on the SAME
computer (in different directories or such). If yes, do they work when
both are running on the sender computer? When both are running on the
receiver computer? If yes, the intervening network might have filters
of firewalls of some sort. If not, the problem is much more likely to
be with the code (as any computer should be able to send something to
itself).

You never tell us whether the "gets size" returns a value and whether
the value is correct. If yes, then the whole networking part may be a
red herring, since all the networking related functions obviously
work. What if you send not just the size, but, say, a 5000 character
string of which the first part is the size (just to test whether
there's a problem when you're sending more than an MTU's worth of
characters).

Since you say you have trouble with binary files, can you send a text
file? That would tell us something one way or another.

At this point:

set size [file size $file]
...
set data [read $fid $size]

you are quietly assuming that $size data was actually read. Why not
test that? Why not simply

set data [read $fid] ;# this reads through EOF
set size [string length $data]

just to make sure?

(you are also opening 'fid' but closing 'fiid').

And why not use something like this http://cr.yp.to/ucspi-tcp.html
for primitive file transfer? Or even better - remote mounted ("mapped"
in windows lingo) drives? Which would give you all the usual file
access control features? Why re-invent a wheel here?


cordially

Y.T.

Remove yourclothes before you email me.
From: Ralf Fassel on
* Debby Luebke <debby.luebke(a)gmail.com>
| i tried to put all stuff in header and scan length as you suggested in
| a neighbor thread to a collegue but then i get only size and no file
| contents at the host end. can't figure out why.

You may need to flush (or close) the socket on the sender side in order
to actually send all data.

| > 2) you need to set the socket blocking in "set_file"
| thanks, will try blocking -none

No, he meant *do* use blocking mode (but that is the default anyway
IIRC). You will get short reads with blocking=false on network
connections.

R'
From: tom.rmadilo on
On Jan 16, 11:14 am, "Gerald W. Lester" <Gerald.Les...(a)cox.net> wrote:
> Debby Luebke wrote:
> > hi Tcl-ers:
>
> > i have a problem  reading binary files from channel on the host
> > computer.
>
> > host computer info is as follows: MS Win 2003 server with SP2 and Tcl
> > 8.5.7.0
>
> > i gave a thorough read to article athttp://wiki.tcl.tk/1180. i
> > follow all the rules explained but no file gets thru .
>
> > # Setter
> > proc set_file { file sock } {
> >     set size [file size $file]
> >     fconfigure $sock -translation binary
> >     set fid [open "$file" r]
> >     fconfigure $fid -translation binary
> >     set data [read $fid $size]
> >     puts $sock $size
> >     puts -nonewline $sock $data
> >     close $fiid
> > }

First might be a type in close $fiid --> $fid.

> 1) with binary files do not use gets use read
> 2) you need to set the socket blocking in "set_file"

I would change the first proc to use fcopy. Blocking mode is not
necessary on the server, it helps on the client.

You could read the size, use puts and flush so the client gets the
data. Then set -translation binary:

proc ::serve_file {file sock} {
set size [file size $file]
puts $sock $size
flush $sock
fconfigure $sock -translation binary
# in 8.5 chan configure $sock -translation binary
set fid [open $file r]
fconfigure $fid -translation binary
fcopy $fid $sock -command [list ::Cleanup $fid $sock]
# in 8.5 chan copy $fid $sock ...
}

# copy from vwait manpage:
proc ::Cleanup {in out bytes {error {}}} {
global total
set total $bytes
close $in
close $out
if {[string length $error] != 0} {
# error occurred during the copy
puts stderr $error
}
}

# You still have to create a server socket from socket mannpage:

proc ::Server {channel clientaddr clientport} {
puts stderr "Connection from $clientaddr registered"
::serve_file /tmp/file.txt $channel
}

socket -server ::Server 9900
vwait forever

From: tom.rmadilo on
On Jan 21, 8:07 am, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:

> socket -server ::Server 9900
> vwait forever

Then in tcl the client using a command line:

% socket localhost 9900
sock3
% gets sock3
52
% fconfigure sock3 -translation binary
% set x [read sock3 52]
this is a test
another line here
still another line

% close sock3
% string length $x
52