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

Hello monks, I am trying to use the fileevent feature of Perl/Tk under Win32.
My test code is the following:
#!/usr/bin/perl use strict; use Tk; use IO; use IO::Socket::INET; my ($server, $server_port, $maxlisten); $maxlisten=5; if (@ARGV<1) { $server_port=9876; } else { $server_port=shift; } $server = IO::Socket::INET->new(LocalPort => $server_port, Type => SOCK_STREAM, Reuse => 1, Listen => $maxlisten ); my $top = MainWindow->new(); $top->fileevent($server, 'readable' => \&recedata); MainLoop(); sub recedata { warn "in recedata\n"; my $data; my $n=80; my $client=$server->accept(); if(sysread($client,$data,$n)<0) { die "Error in socket read\n"; } print "$data\n"; # my $data=<$client>; my $t2 = $top->Scrolled('Text'); $t2->pack(-expand => 1, -fill => 'both'); tie (*TEXT2, 'Tk::Text',$t2); print TEXT2 "$data\n"; }
and it works fine under Mac/OS.
It does not work under Win32 (I tried Windows 2000 and Windows XP).
I used "nc" to send data to the listening socket and by looking at the
connections (by means of "netstat") it appears that the connection is
established.
However the fileevent is not triggered and the subroutine
"recedata" is never invoked.
I am using the latest available Perl for Win32 from ActiveState (5.8.4)
Can you provide any hint?

Replies are listed 'Best First'.
Re: Tk fileevent with win32 sockets
by keszler (Priest) on Aug 16, 2004 at 20:13 UTC
    My experience has been that the types of filehandles that "work properly" under Windows is a null set.

    In a recently developed program I ended up using a 'master' program to handle the GUI and its events, and a 'slave' program to handle all the socket-based IO (LWP::Useragent et. al. in this case). The two programs used Tie::Win32MemMap (and thus Win32::MemMap) to pass data back and forth.

    The tkcomics example from O'Reilly's Mastering Perl/Tk shows a good example of this, and a good method of writing a multi-platform program that selects the use of filevents or Tie::Win32MemMap in a BEGIN block.

      In the end I found that a "reasonable" tradeoff in term of portability is
      the following solution based on "select" and "repeat".
      use IO::Select; my ($server, $server_port, $timeout, $maxlisten); $maxlisten=5; $timeout=50; if (@ARGV<1) { $server_port=9876; } else { $server_port=shift; } my $top = MainWindow->new(); $server = IO::Socket::INET->new(LocalPort => $server_port, Type => SOCK_STREAM, Reuse => 1, Listen => $maxlisten ); $top->repeat($timeout,[\&recedata, $server]); MainLoop(); sub recedata { my $server=shift; my $s=IO::Select->new($server); my @ready=$s->can_read(0); if ($ready[0] == $server) { warn "in recedata\n"; my $client=$server->accept(); my $data=<$client>; print "$data\n"; my $t2 = $top->Scrolled('Text'); $t2->pack(-expand => 1, -fill => 'both'); tie (*TEXT2, 'Tk::Text',$t2); print TEXT2 "$data\n"; close ($client); } }
      Thanks to all people who replied to my question!
Re: Tk fileevent with win32 sockets
by ikegami (Patriarch) on Aug 16, 2004 at 17:07 UTC
    The fileevent Tk doc states "On windows platforms fileevent is limited in the types of filehandles that behave correctly." Not sure if that's relevant. Anyone know?
      I always had the impression that at least sockets would work on Win32 with fileevent.
      If 'behave correctly' means behaves like Unix filehandles then sockets are the only handles (AFAIK) on windows that get even close.