Beginner writing client - help! 
Author Message
 Beginner writing client - help!

I'm just learning TCL, so bear with me if I ask some stupid questions.
I think I've got the hang of the idea behind the commands fileevent,
socket, and gets, so I figured I'd try putting them all together to
write a simple TCP client - maybe a query to my POP3 server or check
the weather by telnetting into rainmaker.wunderground.com and sending
the commands to list my city.

I figured out quickly enough that I can't just gets $socket; as
long as there's no data the application locks up while I wait for
the server and it waits for me.  So I read up on fileevent, and
found a few examples floating around that show how to apply
fileevent to a socket.  Here's where I ran into trouble.  My
fileevent says this:

  fileevent $nSocket readable {
    set cIn [gets $nSocket]
    set lDone 1
    set nRetVal [string length $cIn]
  }

  ... then I've got a while !$lDone that either times out or
  halts when I've got some input.  Great - except it doesn't
  work; it times out without ever getting any data.

All the examples I've seen look like this:
  fileevent $sock readable [list svcHandler $sock]

My questions are:

1) What's wrong with my approach?
2) Why list?  What earthly purpose does list have with regards to
   waiting for data to be available from the socket?  Maybe this
   is foreign to me because I'm a procedural coder who never
   quite caught on to OOP, but everything I've read about tcl's
   list-related commands leaves me wondering what a list has to
   do with a socket.

Help!

---------
If you reply by email, use pbs002 at hotmail dot com.  All
adverti{*filter*}ts will be returned with complaints to your postmaster,



Fri, 11 Aug 2000 03:00:00 GMT  
 Beginner writing client - help!

Quote:

> I'm just learning TCL, so bear with me if I ask some stupid questions.
> I think I've got the hang of the idea behind the commands fileevent,
> socket, and gets, so I figured I'd try putting them all together to
> write a simple TCP client - maybe a query to my POP3 server or check
> the weather by telnetting into rainmaker.wunderground.com and sending
> the commands to list my city.

> I figured out quickly enough that I can't just gets $socket; as
> long as there's no data the application locks up while I wait for
> the server and it waits for me.  So I read up on fileevent, and
> found a few examples floating around that show how to apply
> fileevent to a socket.  Here's where I ran into trouble.  My
> fileevent says this:

>   fileevent $nSocket readable {
>     set cIn [gets $nSocket]
>     set lDone 1
>     set nRetVal [string length $cIn]
>   }

>   ... then I've got a while !$lDone that either times out or
>   halts when I've got some input.  Great - except it doesn't
>   work; it times out without ever getting any data.
> All the examples I've seen look like this:
>   fileevent $sock readable [list svcHandler $sock]

> My questions are:

> 1) What's wrong with my approach?

I suspect your problem is that you are never entering the event loop.
In Tk, this is generally behind-scenes-magic (unless you do something
that blocks).  In Tcl, you must take care to use [vwait] or [after] to
allow events to be processed.  For example (untested):

    proc HandleSocket { channel } {
        global lDone
        if { [eof $channel] } {
            set lDone 1
        } else {
            set cIn [gets $channel]
        }
    }

    ...
    fileevent $channel readable [list HandleSocket $channel]
    vwait lDone

Quote:
> 2) Why list?  What earthly purpose does list have with regards to
>    waiting for data to be available from the socket?  Maybe this
>    is foreign to me because I'm a procedural coder who never
>    quite caught on to OOP, but everything I've read about tcl's
>    list-related commands leaves me wondering what a list has to
>    do with a socket.

fileevent wants THREE (3!) arguments: the channel, the event, and the
script.  Your script COULD get the channel ID from a global but it is
more flexible, maintainable, etc. if you pass the channel ID.  

To group the script name and channel ID into one argument, you can use
[list], quotes, or braces ({}).

Braces suppress evaluation so:

    fileevent $channel readable {HandleSocket $channel}

will leave the argument to HandleSocket unevaluated.

Quotes, in general, are not a reliable grouping mechanism because of
embedded whitespace, etc.

[list] groups the parts of the script argument BUT allows $channel to be
evaluated.

Hang in there.  Event driven programming is a different world but once
you get the hang of it, it's incredible.  

When writing an event handler, it helps you to think in terms of
preconditions, postcondistions, and effect: Under what conditions do you
want this procedure to be called (or, under what conditions will the
system call it)?  What does it do?  What is the state of the universe
(or your application) when your procedure it through?  

When you get this focused and can write REALLY LOOSELY COUPLED procs,
your application can be VERY stable and VERY maintainable.  Do NOT write
multi-purpose handlers that respond to every which event and branch on
some condition.  Also consider that because multiple events might be
queued up, etc. you generally want event handlers to be short and to NOT
have side effects beyond queueing up data for another handler that runs
at a lower priority.

Hope this helps.

                                     Chris
--
As MIT is not "Massachusetts" neither is RPI "Rensselaer"



Fri, 11 Aug 2000 03:00:00 GMT  
 Beginner writing client - help!



Quote:
>  fileevent $nSocket readable {
>    set cIn [gets $nSocket]
>    set lDone 1
>    set nRetVal [string length $cIn]
>  }

>  ... then I've got a while !$lDone that either times out or
>  halts when I've got some input.  Great - except it doesn't
>  work; it times out without ever getting any data.

>1) What's wrong with my approach?

Use 'vwait lDone' instead of the while loop.  Otherwise Tcl's event
loop is never entered, and the 'readable' event on your socket is
never detected.  See the man page for 'vwait'.

Quote:
>All the examples I've seen look like this:
>  fileevent $sock readable [list svcHandler $sock]

>2) Why list?  What earthly purpose does list have with regards to
>   waiting for data to be available from the socket?  ....

Why did you enclose your 'fileevent readable' script in curly braces?
In order to group all those lines into a single argument to the
fileevent command, that's why.  Likewise, the Tcl command 'list' groups
its arguments into a single argument of the fileevent command.  A Tcl list
has nothing to do with reading data from a socket, you are right, but it
has everything to do with the formation of valid Tcl commands.

--
| Don Porter, D.Sc.   Mathematical and Computational Sciences Division |

| http://math.nist.gov/mcsd/Staff/DPorter/                        NIST |
|______________________________________________________________________|



Fri, 11 Aug 2000 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Help writing client/server scripts

2. win32com.client -- beginner question

3. How to write a thin client

4. Writing to Client Area of Window

5. Writing to Client Area of Window

6. Release of Concorde v0.10 (an email client written in Python)

7. Writing an Email Client With HTML Message Support?

8. Writing a secure web client?

9. Hard to write FTP client?

10. Any W3 clients written in TK?

11. PYTHON: problem using file.write method (stupid, beginner)

12. SICP: Evaluation by re-writing? (beginner)

 

 
Powered by phpBB® Forum Software