Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
I am trying to write a perl/Tk application that also acts as a socket server. The socket server accepts connections from TCP clients, and outputs data to those clients regularly. The Tk application uses fileevent() to handle multiple clients in a single process.
Output to each client is buffered, i.e. when there is data to be sent to each client I enable a 'writable' fileevent on that socket, and write data out when the socket is writable.
I am getting the following error when I try to set the 'writable' fileevent:
Tk::Error: fileno not same for read 7 and write 8 at /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/Tk/Event/IO.pm line 115.
Does anyone know why this is? I'm using perl 5.8.0 and perl-Tk800.025 on RedHat Linux 9. Sample code is attached.
#!/usr/bin/perl use strict; use Tk; use IO::Socket; my $mw = MainWindow->new; my $clients = {}; $mw->title('Hello World'); $mw->Button(-text => 'Done', -command => sub { exit })->pack; # Setup server socket my $server = IO::Socket::INET->new ( LocalPort => 40000, Type => SOCK_STREAM, Reuse => 1, Listen => 10) or die "Couldn't be a tcp server on port 40000: $@\n"; # trigger on reads $mw->fileevent ($server, 'readable', \&server_read); # trigger every 1 second $mw->repeat (1000, \&event_tick); MainLoop; sub server_read { # get new client my $new_client = $server->accept (); my $socket_no = $new_client->fileno(); print "Got new client #" . $socket_no . "\n"; $clients->{$socket_no} = { -socket => $new_client, -buffer => '' }; # trigger on any read events (usually client disconnecting) $mw->fileevent ($new_client, 'readable', [\&client_read, $socket_n +o]); }; sub client_read { my ($socket_no) = @_; my ($buf, $len); my $client= $clients->{$socket_no}->{-socket}; $len = $client->sysread ($buf, 1024); print "Read $len bytes from client $socket_no\n"; if ($len == 0) { # client has disconnected print "client $socket_no has disconnected\n"; $mw->fileevent ($client, 'readable', ''); $mw->fileevent ($client, 'writable', ''); $client->close(); } else { print "received [$buf] from client\n"; }; }; sub event_tick { my $time = time; my $localtime = scalar (localtime($time)); # write to all the clients foreach my $socket_no (keys %$clients) { print "adding to buffer for client $socket_no\n"; $clients->{$socket_no}->{-buffer} .= $localtime; my $client = $clients->{$socket_no}->{-socket}; $mw->fileevent ($client, 'writable', [\&client_write, $socket_ +no]); }; }; sub client_write { my ($socket_no) = @_; my ($len); print "client $socket_no is writable!\n"; my $client = $clients->{$socket_no}->{-client}; $len = $client->syswrite ($clients->{$socket_no}->{-buffer}); print "wrote $len bytes to client $socket_no\n"; if ($len == 0) { # buffer emptied print "buffer for $socket_no emptied\n"; $clients->{$socket_no}->{-buffer} = ''; $mw->fileevent ($client, 'writable', ''); } else { # buffer partially emptied $clients->{$socket_no}->{-buffer} = substr ( $clients->{$socket_no}->{-buffer}, $len); }; };
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Tk & Socket: Tk::Error: fileno not same for read X and write Y
by pg (Canon) on Oct 14, 2003 at 17:26 UTC | |
by bbfu (Curate) on Oct 15, 2003 at 02:37 UTC | |
|
Re: Tk & Socket: Tk::Error: fileno not same for read X and write Y
by bbfu (Curate) on Oct 15, 2003 at 02:32 UTC | |
by dotsha (Initiate) on Oct 15, 2003 at 07:20 UTC | |
|
Re: Tk & Socket: Tk::Error: fileno not same for read X and write Y
by dotsha (Initiate) on Oct 15, 2003 at 09:23 UTC |