Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

endless loops for server and tk

by hudo (Novice)
on Aug 02, 2007 at 10:01 UTC ( #630244=perlquestion: print w/replies, xml ) Need Help??
hudo has asked for the wisdom of the Perl Monks concerning the following question:

The platform is windows xp. There should be only ONE programm/dos-window.

I need a UDP server on the xp machine who is sending constantly (every n seconds) to 5 clients (SPS) in a LAN even if the clients do not send a request (UDP is not reliable, maybe the SPS are dead).
The server is also receiving periodically requests from the clients and then responding them (normal operation of the system).
The requests should be displayed graphically (for instance with a perl/tk listbox).

How can I manage the timing, because in my opinion there are several endless loops
* the server should send
* the server should receive
* the endless loop of the perl/tk MainLoop with the periodically refreshed listbox.

For the perl/tk MainLoop I asked in this forum "listbox refresh with Tk::After" and got a working answer with the command repeat.

I got a server who receives/listens and responds immediately to request in a while (1){} loop. How can I integrate, that the server should also send periodically if there are no requests ? Maybe a timeout for the receiving loop ?

How can these demands be integrated in one programm ?

I would have thought of two different programms , a server and the graphically perl/tk programm, where the programms communicate via files, but there should be only ONE doswindow. Maybe it is possible to let the doswindow dissappear after e.g. the perl/tk programm is started ?

A last problem, the client who is not requesting after m seconds should be marked with a different color in the perl/tk GUI, for instance his last request should have a red background, all others have a green background. I think this is not possible with a normal listbox. What alternative would you suggest ?

I appreciate each hint, thanks in advance.

Replies are listed 'Best First'.
Re: endless loops for server and tk
by zentara (Archbishop) on Aug 02, 2007 at 11:05 UTC
    Show us a simple example of what you have so far. You can search for "perl tk udp", and " udpqotd - UDP message server". You can avoid the dos window by using wperl instead of perl in your shebang line. What you want to do is possble, but no one will write it for you( for free). :-)

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: endless loops for server and tk
by strat (Canon) on Aug 03, 2007 at 10:09 UTC
    If you need to split up MainLoop so you can integrate it into another loop, you can try something like:
    while( .... ) { # some non-blocking stuff if( Tk::MainWindow->Count ) { local $inMainLoop = 1; DoOneEvent(0); } # if else { # no more mainwindows, finish somehow } # else # other non-blocking stuff } # while

    (not tested; see: -> MainLoop)

    But that may (or may not) become dangerous if is changed in future

    Best regards,
    perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8."

      Sorry for the format of my last posting, I have two questions to the formatting.

      How can I write a "general" reply, not a reply to a answer of a certain user ? Is it the "Comment on" link ??

      How can I have the source code only as a download link like user strat or Errto has ? In each readmore section seems to be all of my source code sections. Is this normal or did I misunderstood something ?
      Thanks for the help.

Re: endless loops for server and tk
by vkon (Curate) on Aug 02, 2007 at 15:38 UTC
    this is perfectly possible with Tcl/Tk GUI with Tcl::Tk CPAN module.

    Tcl/Tk has fileevent which resolves the problem.

    I have written bluetooth COM-keyboard driver this way, which works both for linux and windows. The essential part is

    use Tcl::Tk; my $int = new Tcl::Tk; # ..... $int->fileevent($fhbt, readable => \&process_keyboard); # .... $int->MainLoop;
    This is what you asked - file operations awake callbacks when in GUI MainLoop.
Re: endless loops for server and tk
by BrowserUk (Pope) on Aug 02, 2007 at 15:48 UTC

    Write 3 simple applications.

    1. Just sends every 5 seconds.
    2. Just receives and does what it needs to do.
    3. The Tk application that draws what you want to appear.

    Test them individually.

    When you are satisfied with them. come back, post the code and we can show you how easy it is to put the code from the each of the first two into its own thread, share whatever needs sharing and viola, you have your integrated application.

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Hello, I'll post some code that I have at the moment.
      The server accepting requests and responding immediately to the clients is here Normally the server reads from a mysql table and compares the request content to the table content, and updates eventually the mysql table.
      This is at the moment comment.
      The code for the client sending request after n seconds is here In the client I tried to let him receive the server-response with a timeout, but I did not succeed. Maybe some hints ? The client should continue to send every n seconds a request even if there is no server listening.
      By the way, when using the client on a xp machine it stops at the first time he receives (server is listening) when the server includes $startzeit in his response.
      If the client runs on ubuntu (vmware guest system) he receives the whole response if the response does not include $startzeit, but with the server code $sock->send("Zeitstempel: $startzeit : Du sagtest: ''$nachricht'' zu mir $/"); or   $sock->send("Zeitstempel: ''$startzeit'' : Du sagtest: ''$nachricht'' zu mir $/"); the client receives not the whole response or at least prints not the whole response to STDOUT. What could be here the problem ?

      Here is the actual contents of meinfile.txt which corresponds to the request:

      A first Tk code is here: If I edit the contents of the meinfile.txt in an editor, the changes are displayed immediately in the listbox.
      The listbox should later display the data of the mysql table which should be updated depending on the clients requests.

      vkon, I tried to implement the Tk code with fileevent, but I did not succeed. Here is my code:

      BrowserUk, the client code could be used as the server "just sending every 5 seconds".
      By the way, how could this be implemented,that the server listens to all UDP ports, not only to a specific. Later there are e.g. 5 clients, each sending on his on port (e.g. from 10001 to 10005) and the server should listen to all of these ports simultaneously, thats why I thought of listening to all UDP ports.

        Okay. Here are three separate minimal programs, and one composite that joins them all together. I have used your Tk program, cleaned up a lot. Sorry that your comments are missing, but I don't read Gernman and they were just in the way of seeing what was going on. You should really try to be a little more consistant with your code layout also.

        This is the standalone server that listens and responds to 5 different udp ports:

        And this is the standalone client. It talks to all of the ports on the server for testing and demo, but would normally only talk to one. When used as the heartbeat thread withing the combined app, it would also talk to all 5 clients.

        And here is my cleaned up and working version of your Tk code. I am posting it separately because you should maintain all 3 standalone apps as testbeds and reference points, as well as the combined app. It is much easier to test changes in the individual apps and, once you are satisfied they are working, c&p the changes into the combined app. It make seem extra work, but think of the separate apps and testcases.

        And finally, the combined, threaded app. The modifications are minimal. Each thread is a direct C&P from the standalone version.

        In particular, there is very little shared data, as it is not clear what else you want to do or what else you need to share, but it should give you a starting point. My purpose is to demonstrate the simplicity of combining the code.

        After that, you are responsible for adding whatever extras you need. I'm willing to help you make your additions, but please don't post reams and reams of code with huge chunks commented out and reams and reams of comments that I cannot understand--just delete them from the post--otherwise I am apt to be put off.

        To answer your question from Re^2: Displaying text in columns, I've used spoiler tags, rather than readmore tags, despite this usage being frowned upon, because spoiler tags do not get expanded until you choose to click on them whereas readmore tags are expanded whenever you view the post directly. This way, you can read the text of the post as a coherent whole without having to scroll past loads of code.

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: endless loops for server and tk
by Errto (Vicar) on Aug 03, 2007 at 04:50 UTC
    A couple of general points. One, yes, add a timeout to your receiving loop. In a similar example, I just used the timeout method of the IO::Socket module. That was for TCP, but I assume there's a UDP equivalent. Second, you can use the fact that you now know you'll iterate through your loop once every some interval, you can use that opportunity to call $mw->update. So the outline is:
    # setup MainWindow $mw # setup socket with timeout sub myloop { while (1) { #read from socket; #if anything read, deal with it; $mw->update(); } } $mw->after(1, \&myloop); MainLoop;
    This way the main loop initializes itself and renders your window, but then your code takes over and does the GUI update as often as needed.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://630244]
Approved by Corion
Front-paged by Courage
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (10)
As of 2017-01-18 14:23 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (161 votes). Check out past polls.