in reply to Server with GUI

Please point me in the right direction.

Since you are new to Perl, I will give you some tips. In any GUI, if you run a while loop( or sleep ) as you do in your code, you will interfere with the GUI's eventloop, which is the line $app->MainLoop; That will make the GUI freeze unless you manually update the mainwindow everytime thru the loop. You just can't mix conventional Perl code with GUI code, and expect it to run.

You can run a network while loop with a GUI front end, but the network loop must be in a separate thread. This however, is generally not a problem with GUI's because almost every GUI toolkit has a fileevent or IO watch method, which allows the GUI to watch the network without a while loop. I googled for it, and was surprised to read that Wxwidgets has no filehandle watch. See AnyEvent for a workaround. Maybe a Wx guru knows a better way.

To show how it should work, using Tk , see Re: hanged In Tk-socket program. In that server, I make the socket before the GUI pops up, and use a fileevent to handle incoming connections. This is probably the simplest example possible.

You might want to switch to Tk if you don't understand how Wx or GUI's work. For more complex Tk server-client pairs, see ztk-enchat encrypted server client and Tk encrypted echoing-chat client and server

Once you get the idea of how it is supposed to work with Tk, then you can go back and try to do the same thing with Wx. Sockets are not intuitively obvious to make run correctly.


I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh

Replies are listed 'Best First'.
Re^2: Server with GUI
by gg4000 (Novice) on May 28, 2012 at 17:15 UTC
    Thank you for the quick reply.

    I do have a script the same as this using Tk. It has been doing the same thing as Wx. I will do what you suggested and use Tk.

    Tk will not install on my desktop, but will on my laptop. I'd love to see the fireworks on the desktop! So I've been doing the work on the desktop, then email it to the laptop to test.
      Tk will not install on my desktop

      If you post what operating system you have, and OS level, someone may be able to help you get Tk on your Desktop. I'm assuming it's Windows?


      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku ................... flash japh
        Win 7

        Get's the error can't locate @INC

        Path= c:\mingw\bin;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;C:\Dwimperl\perl\bin;C:\Dwimperl\perl\site\bin;C:\Dwimperl\c\bin;C:\strawberry\cpan\build\Tk-804.030-23IFwa;

        Get the error Seems impossible to install.

Re^2: Server with GUI
by gg4000 (Novice) on May 29, 2012 at 23:41 UTC
    I Got FireWorks!!! : ) Last night I did a fresh install of Strawberry. Today Tk was installed. I tried the Re: hanged In Tk-socket program, but I did not see the typed text from the client to the server. Did I do something wrong? I typed Hello in the client, hit enter with the server running, but nothing happened.
      I did not see the typed text from the client to the server.

      You may have a Window's related problem, where Tk's fileevent dosn't work reliably on some version of windows. See Client/Server sockets with TK on Win32 .

      There are workarounds, see Another Win32 Tk fileevent work around : using ioctl() properly for instance. If that dosn't work for you, it's possible to use a conventional select loop with sysread in a separate subroutine, and call it with a Tk timer every 10 milliseconds. See Tk fileevent with win32 sockets for a timer solution.

      It goes something like this untested code:

      ... other Tk code my $timer = $mw->repeat(10, \&read_it ); MainLoop; sub read_it{ my $client = $listen->accept or die "Accept failed: $!"; if( IO::Select->new($client)->can_read(5) ) { sysread( $client, $_, 1 ) and print; } else { print "Timeout\n"; } close $client; }

      Also see Mastering Perl/Tk and the Window's fileevent problem

      If you are an eager seeker of Perl knowledge, I will tell you that another, more advanced GUI toolkit, called Gtk2 does have an IO watch ( like fileevent ) which does work on Windows, see Simple threaded chat server for a simple example to test with.

      Finally, you could just put Ubuntu Linux on your Desktop with a dual boot to Windows. :-)

      Finally, just to get you banging your head against the wall, I found an example of Wx using sockets, see Wx Socket. It probably works on Windows.


      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku ................... flash japh
        LOL!!! Finally, just to get you banging your head against the wall, I found an example of Wx using sockets,

        Thanks for all the info. I will play with it when I get home from work.

        Well it's been a long week of trial and error.

        Had things happen with Tk, had things happen with Wx.

        I'm back to the start. Wx.

        The window opens after the server gets a connection. The Window has to open and display the IP First.

        Then display the text from the client. And display the next set of text from the client.

        And send the commands to the computer. I'm still stuck with "What to do instead of While"

        #!/usr/bin/perl package main; use IO::Socket; use Sys::Hostname; use Socket; use 5.008; #use strict; use Wx; use wxPerl::Constructors; use base 'Wx::App'; use Wx qw(wxTE_MULTILINE wxVERTICAL wxID_DEFAULT); #use warnings; my($ipaddr)=inet_ntoa((gethostbyname(hostname))[4]); $| = 1; my $app = Demo::App->new; $app->MainLoop; package Demo::App; #use strict; #use warnings; use base 'Wx::App'; sub OnInit { my $frame = Demo::App::Frame->new; $frame->Show(1); } package Demo::App::Frame; #use strict; #use warnings; use Wx qw(:everything); use base 'Wx::Frame'; sub new { #print "Ready for next command.\n\n"; my ($class) = @_; my $self = $class->SUPER::new( undef, -1, "X10 Voice Commander", wxDefaultPosition, wxDefaultSize, ); $self->{text} = Wx::TextCtrl->new($self, -1, "", [-1,-1], [300, 300], +wxTE_MULTILINE); $self->{text}->AppendText("Use Your IP $ipaddr:8087 on your devi +ce.\n"); #$self->{text}->AppendText("Connection from: ", $addr->peerhost(), +"\n"); #sub serv { $local = IO::Socket::INET->new( Proto => 'tcp', # protocol LocalAddr => "$ipaddr:8087", ) or die "$!"; my $addr; $local->listen(); $local->autoflush(1); while ($addr = $local->accept() ) { print "Connection from: ", $addr->peerhost(),"\n"; while (<$addr>) { $path = "C:/Program Files (x86)/Common Files/X10/Common"; chdir($path) or die "Cant chdir to $path $!"; ~s/GET//,~s/~/ /g,~s/%20/ /g,~s/%22/ /g,~s/x10command=DEVICE/ +/,~s/\//\ /g,~s/[?]//g ,~s/'/ /g,~s/HTTP/ /,~s/1.1/ /g,~s/sh://; system(AHCMD. "$_"); print "Received: $_"; print $addr $_; print $path $_; close $addr; chomp; return $self; } } }

        And a test client.....
        use IO::Socket; use Sys::Hostname; my($ipaddr)=inet_ntoa((gethostbyname(hostname))[4]); $remote = IO::Socket::INET->new( Proto => 'tcp', # protocol PeerAddr=> "$ipaddr:8087", PeerPort=> "8087", # port of server Reuse => 1, ) or die "$!"; print "Connected to ", $remote->peerhost, # Info message " on port: ", $remote->peerport, "\n"; $remote->autoflush(1); # Send immediately while (<>) { # Get input from STDIN print $remote " "; print $remote "sendplc "; print $remote $_; # Send to Server #last if m/^end/gi; # If 'end' then exit loop my $line = <$remote>; # Receive echo from server if ($line ne $_) { # If not the same as input #print "Error in sending output\n"; # error exit; # Terminate } print "End of client\n"; # End of client close $remote; # Close socket exit }
        Run the server first. Type anything into the client. Commands are if you have X10 installed "A1 On"
      Tk does work with the command prompt. Tk will not work with Padre.

      Can't locate Tk.pm in @INC (@INC contains: C:/Dwimperl/perl/site/lib C:/Dwimperl /perl/vendor/lib C:/Dwimperl/perl/lib .) at monkserver.pl line 5.

      Seems like it should be easy to fix, but I don't know what a @INC is.