Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Listening Socket in Tk

by avo (Pilgrim)
on May 07, 2005 at 20:35 UTC ( #454930=perlquestion: print w/replies, xml ) Need Help??

avo has asked for the wisdom of the Perl Monks concerning the following question:

Good Evening Monks, I've been playing arround with Tk for a while and I came up with a working prototype of a POS (Point of Sale) which I use for couple of months in couple of restaurants ( However - In my scenario my server is plain (no GUI) Perl application that is forking for each of my clients... Socket that listens for the connections from my POS clients... The problem that I have is that the comunication is only one way - which means that I don't have socket that listens on the Tk (client) side. So shorter - I do the following: Client sends request to the server and gets reply from the server. I just want to add to this - "Server sends request to the client and client answers" ie... full duplex comunication. My problem is that Tk has got it's own event loop - so I can not have something like "while(1) ..." in the Tk program. I tried using POE with Filter::Reference and Socket Wheel on top of Tk... but it slows down my comunication speed dramticaly... For example my server response time jumped from 0.0001 seconds to 0.3 / 0.4 seconds - which is unaceptable for me. I tried everything - but it looks that I am not lucky. Can you please help me. In two words - I need Tk application example for a program that acts as a client and a server in a non-blocking manner using either Fork or Threads, something that will run fine on Active State Perl. I can not afford using IO::Select because of the server multitasking required... Thank you for your expertise.

Replies are listed 'Best First'.
Re: Listening Socket in Tk
by Errto (Vicar) on May 08, 2005 at 00:07 UTC
    You can do this with a non-blocking socket and Tk's repeat method (see Tk::after). This is untested, but something like it should work:
    sub checksocket { my ($sock) = @_; my $data; $sock->read($data, $nnn) # replace $nnn with number of bytes you +want or return; # no data read # do something with $data here } my $mw = MainWindow->new; # set up your Tk widgets here my $sock = IO::Socket::INET->new(PeerAddr => 'host:port', Proto => 'tcp', Blocking => 0); # set non-blocking mode my $after = $mw->repeat(500, # set to appropriate number of milis sub { checksocket($sock) } ); MainLoop;
    This will cause Tk to do its usual thing, except that it will interrupt the event loop every however-many milliseconds to call your subroutine, which will attempt to read data from the socket in non-blocking mode.
Re: Listening Socket in Tk
by merlyn (Sage) on May 08, 2005 at 00:53 UTC
    If the same process is managing the screen and listening on the socket, you'll have some random amount of latency. There's no way around that. There will be times when your socket goes ready that Tk is busy thinking about the screen.

    If you need to isolate the latency, put your communication protocol in a second process, and when it has an entire update for the Tk process, it can tap the Tk process on the shoulder and say "here's your new data". I'd do that with two cooperating POE processes (one POE-Tk, one just POE), or maybe an loop for the latter.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: Listening Socket in Tk
by zentara (Archbishop) on May 08, 2005 at 10:48 UTC
    You can use Tk's fileevent as in the example below. Start the server, and as many clients as you want. (Not tested on Windows) and I'm not entirely sure what you want. Also alot of error checking is left out. I like to use Net::EasyTCP for this type of thing. It can be used with Tk, by the method shown by Errto, of putting the socket checking into a "repeat" statement( but that is getting away from your question. See ztk-enchat encrypted server client).

    I'm not really a human, but I play one on earth. flash japh
      This is very good. It works on Linux! I was just wondering how to get this to work under Windows :( Does anyone know how to get Tk::Fileevent to work on Active Perl 5.8.3+ ? Thanks guys I realy apreciate all your input!!!
        I'm afraid that fileevent is broken on Win32. I wanted to use it to monitor a logfile in one cross-platform Tk app, but I had to resort to polling when $^O eq MSWin32. :(
Re: Listening Socket in Tk
by spurperl (Priest) on May 09, 2005 at 10:06 UTC
    You can use threads (the "threads" module) to achieve this task. It works fine on Windows with Active Perl (version >= 5.8).

    Making threads friends with Tk is a little bit tricky, but it certainly can be done and works just fine.

    Here you can see what I've done with threads and Tk to work full duplex with a serial port, sockets should be very similar, and even simpler because socket support is very mature in Perl.

    It works nicely on Windows with Active Perl.

      The problem is fixed. I just found that there is this in POE's Tk Loop for Active State Perl:

      $_handle_poller = $poe_main_window->after(100, [\&_poll_for_io]);

      This basicaly handles events while Tk is idle, which explains everything... All I did is I've changed the after time:

      $_handle_poller = $poe_main_window->after(1, [\&_poll_for_io]);

      Now I have no delays of any kind... my server is responding to my client immediately. Please don't hesitate to contact me for more information on this issue. As a conclusion I would like to recommend POE for proper Server-Client application on top of Tk. The things POE does is just pure magic. I personaly think that POE rocks!
      Keep the good work Rocco!!
      Anyway, Thank you all for the time and the suggestions!!

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://454930]
Approved by Tanktalus
Front-paged by strredwolf
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2021-10-26 00:40 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (90 votes). Check out past polls.