Tcl I/O is based on a the concept of channels. A channel is conceptually similar to a
FILE * in C, or a stream in shell programming. The difference is that a channel may be a either a stream device like a file, or a connection oriented construct like a socket.A stream based channel is created with the
open command, as discussed in lesson 26. A socket based channel is created with a socket command. A socket can be opened as either as a client, or as a server.If a socket channel is opened as a server, then the tcl program will 'listen' on that channel for another task to attempt to connect with it. When this happens, a new channel is created for that link (server-> new client), and the tcl program continues to listen for connections on the original port number. In this way, a single Tcl server could be talking to several clients simultaneously.
When a channel exists, a handler can be defined that will be invoked when the channel is available for reading or writing. This handler is defined with the
fileevent command. When a tcl procedure does a gets or puts to a blocking device, and the device isn't ready for I/O, the program will block until the device is ready. This may be a long while if the other end of the I/O channel has gone off line. Using the fileevent command, the program only accesses an I/O channel when it is ready to move data.Finally, there is a command to wait until an event happens. The
vwait command will wait until a variable is set. This can be used to create a semaphore style functionality for the interaction between client and server, and let a controlling procedure know that an event has occurred.Look at the example, and you'll see the
socket command being used as both client and server, and the fileevent andvwait commands being used to control the I/O between the client and server.Note in particular the
flush commands being used. Just as a channel that is opened as a pipe to a command doesn't send data until either a flush is invoked, or a buffer is filled, the socket based channels don't automatically send data.socket -servercommand?options?port- The
socketcommand with the-serverflag starts a server socket listing on portport. When a connection occurs onport, the proccommandis called with the arguments:channel- The channel for the new clientaddress- The IP Address of this clientportThe port that is assigned to this client
socket?options?hostport- The
socketcommand without the-serveroption opens a client connection to the system with IP Addresshostand port addressport. The IP Address may be given as a numeric string, or as a fully qualified domain address. - To connect to the local host, use the address 127.0.0.1 (the loopback address).
fileeventchannelIDreadable?script?fileeventchannelIDwriteable?script?- The
fileeventcommand defines a handler to be invoked when a condition occurs. The conditions arereadable, which invokesscriptwhen data is ready to be read onchannelID, andwriteable, whenchannelIDis ready to receive data. Note that end-of-file must be checked for by thescript. vwaitvarName- The
vwaitcommand pauses the execution of a script until some background action sets the value ofvarName. A background action can be a proc invoked by a fileevent, or a socket connection, or an event from a tk widget.
Examples
proc serverOpen {channel addr port} {
global connected
fileevent $chann
set connected 1
el readable "readLine Server $channel"
channel} {
gl
puts "OPENED"
}
proc readLine {who
obal didRead
if { [gets $channel line] < 0} {
$channel;set out 1"
} else
fileevent $channel readable {}
after idle "close
{
puts "READ LINE: $line"
puts $channel "This is a return"
flush $channel;
0} server
set
set didRead 1
}
}
set connected 0
# catch {socket -server serverOpen 330
0server [socket -server serverOpen 33000]
after 100 update
s $sock "A Test Line"
flush $sock
vwait
set sock [socket -async 127.0.0.1 33000]
vwait connected
pu
tdidRead
set len [gets $sock line]
puts "Return line: $len -- $line"
catch {close $sock}
vwait out
close $server

0 Comment:
Post a Comment