Elijah has asked for the wisdom of the Perl Monks concerning the following question:
I have found a way to implement multiple socket connections it have this working quiet well but the problems are:
1) How do I get my "server" program to broadcast what it reveives to all it's sockets?
The following code is what I have so far in the "server" app.
#!/usr/bin/perl -w use strict; use IO::Socket; use IO::Select; $| = 1; # Make program hot! my $sock = IO::Socket::INET->new(Proto => 'tcp', LocalAddr => '192.168.0.100', LocalPort => 7778, Broadcast => 1, Blocking => 0, Reuse => 1, Listen => 1) or die "Can't bind : $@\n"; my $sel = new IO::Select($sock, undef, undef, 0); print "Server now listening for connections!\n" if ($sock); #while ($sock) { # if ($sock->recv(my $data, 1024)) { # print STDOUT "Input detected is: $data\n"; # $sock->send($data); # } #} while(my @queues = $sel->can_read) { foreach my $obj (@queues) { my $new; if($obj == $sock) { # Create a new socket $new = $sock->accept; $sel->add($new); }else { # Process socket if (my $pid = fork()) { # parent: close the connection so we can # keep listening $sel->remove($obj); $obj->close(); }else { # child: deal with connection while ($obj) { #my $recv = $obj->recv(my $data, 1024); #if (defined($recv)) { if (defined($obj->recv(my $data, 1024))) { last if (($data =~ /^quit/i)||($data eq "")); print STDOUT "Input detected is: $data\n"; $obj->send($data); }else{ last; } } #$obj->send("thanks, goodbye\r\n"); # finished with the socket $sel->remove($obj); $obj->close; } } } }
Here is the client gui code:
#!/usr/bin/perl # The following comments are for perl2exe compilation! #perl2exe_include Tk; #perl2exe_include Tk::Text; #perl2exe_include Tk::Menu; #perl2exe_include Tk::Photo; #perl2exe_include Tk::ROText; #perl2exe_include strict; use Tk; use Tk::Text; use Tk::Menu; use Tk::Photo; use Tk::ROText; use IO::Socket::INET; use strict; $| = 1; # Make buffers hot! my ($sock); my $main_title = "pIM v0.3 (Beta Release)"; my $info = $main_title; my $mw = MainWindow->new(); $mw->minsize(qw(300 500)); $mw->title($main_title); # Create main application widgets my $t = $mw->Scrolled("ROText", -scrollbars => 'e', -font => ['Courier +', 8], -background => 'white')->pack(-pady => 3, -padx => 3, -ipady => 3, -ipadx => 3, -side => ' +top', -fill => 'both', -expand => 1); my $ts = $mw->Frame->pack(-side => 'top', -fill => 'x'); $mw->Label(-textvariable => \$info, -relief => 'ridge')-> pack(-side => 'top', -fill => 'x'); my $data = $mw->Scrolled("Text", -scrollbars => 'e', -height => '3', - +font => ['Courier New', 8], -background => 'white')->pack(-pady => 3, +-padx => 3, -ipady => 3, -ipadx => 3, -side => 'left',-fill => 'none', -expa +nd => 0); my $butt = $mw->Button(-text => "Send", -command => \&send)->pack(-pad +y => 3, -padx => 3, -ipady => 3, -ipadx => 3, -side => 'right',-fill => 'none', -exp +and => 0); ##################################################### #Start of menubar creation my $menubar = $mw->Menu; my $file_menu = $menubar->cascade(-label => "~File", -tearoff => 0); $file_menu->command(-label => '~Some Function', -command => sub {return}); $file_menu->command(-label => '~Dis-Connect', -command => \&disconnect); $file_menu->command(-label => '~Grab', -command => \&grab); $file_menu->command(-label => '~Exit', -command => sub {exit(0)}); my $edit_menu = $menubar->cascade(-label => "~Edit", -tearoff => 0); $edit_menu->command(-label => '~Some Function', -command => sub {return}); my $functions_menu = $menubar->cascade(-label => "~Functions", -tearof +f => 0); $functions_menu->command(-label => '~Some Function', -command => sub {return}); my $help_menu = $menubar->cascade(-label => "~Info", -tearoff => 0); $help_menu->command(-label => '~About', -command => sub {return}); $mw->configure(-menu => $menubar); #End of menubar creation ####################################################### my $temp_dir = $ENV{TEMP} || $ENV{TMP} || ($^O eq "MSWin32" ? $ENV{WIN +DIR} : '/tmp'); ###################################################################### +######## # The following code is used to define specific text tags for formatti +ng. $t->tagConfigure("blue", -foreground => "blue"); $t->tagConfigure("red", -foreground => "red"); $t->tagConfigure("orange", -foreground => "orange"); $t->tagConfigure("brown", -foreground => "brown"); $t->tagConfigure("grey", -foreground => "grey"); $t->tagConfigure("green", -foreground => "forest green"); $t->tagConfigure('bold', -font => ['Courier New', 8, 'bold']); $t->tagConfigure('italic', -font => ['Courier New', 8, 'italic']); $t->tagConfigure('bg', -background => 'yellow'); $t->tagConfigure('big_italic', -font => ['Courier New', 18, 'italic']) +; ###################################################################### +####### # Some of my own bindings! #$mw->bind('Tk::Text', '<Control-s>', [\&save_file]); $mw->bind('Tk::Text', '<Control-a>', sub {$t->tagAdd('sel','1.0','end' +)}); #$mw->bind('Tk::Text', '<Control-n>', [\&clear_new]); #$mw->bind('Tk::Text', '<Control-p>', [\&print]); $mw->bind('Tk::Text', '<Return>', [\&send]); $mw->bind('Tk::Text', '<Shift-Return>', [sub {$data->insert("end", "\n +");}]); $mw->bind('<MouseWheel>' => [ sub {$_[0]->yview('scroll', -($_[1] / 120) * 4, 'units');}, Ev('D') + ]); # Automatically prepends $data to called sub's args $data->bind('<KeyRelease>', [\&checkKey,Ev('K')]); ###################################################################### +####### $sock = new IO::Socket::INET->new(PeerPort => '7778', PeerAddr => '192.168.0.100', Blocking => 0, Proto => 'tcp') or $t->insert("end", "Can't bind : $@ +\n"); if ($sock) { my $paddr = $sock->peerhost(); my $pport = $sock->peerport(); $t->insert("end", "Connection to $paddr:$pport successfull...\n\n") +; } MainLoop(); sub disconnect { $t->insert("end", "Connection closed\n"); $sock->close(); undef $sock; } sub checkKey { return; } sub send { chomp(my $text = $data->get("1.0", "end")); if ($sock) { if ($text ne "") { $sock->send($text); $t->insert("end", "<YOU>: $text\n"); $data->delete("1.0", "end"); grab(); } }else{ $t->insert("end", "Error: Not connected!\n"); } } sub grab { my $stat = $sock->recv(my $incoming, 1024); print "stat is $stat\n"; if ($stat) { $t->insert("end", "<USER>: $incoming\n") if ($incoming ne ""); } }
Thanks for any help..
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Two-Part Socket Question.
by pg (Canon) on Aug 31, 2004 at 03:42 UTC | |
|
Re: Two-Part Socket Question.
by sgifford (Prior) on Aug 31, 2004 at 03:08 UTC | |
|
Re: Two-Part Socket Question.
by GreyGlass (Sexton) on Aug 31, 2004 at 04:29 UTC | |
by pg (Canon) on Aug 31, 2004 at 06:53 UTC | |
|
Re: Two-Part Socket Question.
by Popcorn Dave (Abbot) on Aug 31, 2004 at 03:31 UTC | |
|
Re: Two-Part Socket Question.
by Elijah (Hermit) on Aug 31, 2004 at 06:12 UTC | |
by sgifford (Prior) on Aug 31, 2004 at 16:56 UTC | |
by zentara (Cardinal) on Aug 31, 2004 at 14:42 UTC |