in reply to Socket: Server shall send same $line to several clients

Hmm.. You seem to assume that forking is the only way to connect to more that one client at a time, actually you can do it without fork at all, which means the main part keeps a reference to each socket connected, and can easily send data to each of the sockets in the list.
Eg:
my $sockserv = new IO::Socket::INET( LocalAddr => '192.168.1.1', LocalPort => $port, Proto => 'tcp', Listen => 1, Reuse => 1, Timeout => 60); die "Can't create Server ($!)" unless $sockserv; $x = new IO::Select(); $x->add($sockserv); $clients = 0; $sockclient=(); while (1) { my @handles = $x->can_read(); # wait for data foreach $handle (@handles) { if ($handle == $sockserv) { $sockclient = $sockserv->accept() || warn "accept: $!" +; $clients++; if ($clients > 5) { print $sockclient "Sorry, we're full.\n"; $sockclient->close(); } else { $sockclients[$clients] = $sockclient; } $x->add($sockclients[$clients]); } $cl = is_member($handle, @sockclients); if ($cl > -1) { $n_read = sysread($sockclients[$cl], $buf, 1024); return 0 if (!n_read || !length $buf); parse_external_command($buf, $sockclients[$cl]); } } }
Thus you have all clients in @sockclients, and can send data to each one using:
foreach my $sock (@sockclients) { print $sock $data; }
If you need forks tho, you'll need to find some other way to get an array of the sockets.
So maybe you should show us your code.

C.

Disclaimer: Copied partly from working code, not tested as is!

Replies are listed 'Best First'.
Re: Re: Socket: Server shall send same $line to several clients
by Anonymous Monk on Feb 23, 2003 at 10:13 UTC
    Thanks castaway,

    it seems pretty much that this is what I was looking for.
    I was mentally bound to the idea of froking a new kid for each client and therefore I was thinking of forking another kid that reads the file(s) and sends them to all other client-kids. But this seems to me too complicated for Perl, Perl is smarter (than me). But thank Good, that there are guys like you :-)

    I'll soon will try your solutions.
    For now thanks a lot,
    Carl

Re: Re: Socket: Server shall send same $line to several clients
by Anonymous Monk on Feb 24, 2003 at 11:43 UTC
    castaway,

    from your code I was able to go on, thanks for this nice push. I packed the Server & Handle stuff in one package having in mind that I might be able to listen for new clients within a spawned kid and pass the updated valid client-handles to its parent.

    But this failed and want to ask now:

    is there a way to pass those handels or the updated class var.: @CL (which contains all client-handles) to another process?

    package SoServ; #: one server for all clients use IO::Socket::INET; use IO::Select; my @CL = (); #: array of sock.Handles to Clients my $S; #: Socket-Server my $H; #: for IO::Select sub new { #: new Socket-Server my $me = {}; $me->{'a'} = shift; #: loc.Adddress address $me->{'p'} = shift; #: port to connect $S = IO::Socket::INET->new( LocalAddr => $me->{'a'}, LocalPort => $me->{'p'}, Proto => 'tcp', Listen => 1, Reuse => 1, Timeout => 60 ); die "Can't create SoServ ($!)\n\n" unless $S; $H = IO::Select->new(); $H->add($S); return bless $me; } #: wait for new connections sub waitNewConn { my $me = shift; #: either endless (1) or just 2 clients (0): my $withKids = shift; while (1) { # endless Loop if with Kids! # wait timeout-sec and then try again: my $newCL = $S->accept() || next; print $newCL "Hi, guy, nice meeting you\n"; $H->add($newCL); #update @CL instead of:push @CL,$newCL; @CL = $H->can_write(1); # no kid: return after 2 conn. return @CL if (@CL == 2 && !$withKids); } # while (1) } # sub sub clients { return @CL } ####### end packages ############# package main; my $addr = 'localhost'; # hard coded for now my $port = 2345; # dito my $Serv = SoServ::new( $addr,$port ); # start Server # Array of Handles to Clients derived from SoServ->@CL my @Clients = (); my $withKids = 1; # want kids or everyth. in 1 process? if ($withKids) { spawn($Serv); # kid is waiting for new Clients } else { # no kid, waiting here for new (2) Clients @Clients = $Serv->waitNewConn(0); } my $line = ''; my $f = '/home/cas/Data/sp1Min/spAdj.dta'; my $n = 9; # just 9 lines for now open(SP, "< $f") or die "can't open SP: $f: $!"; # while (defined($line = <SP>)) { print $line; # control @Clients = $Serv->clients() if ($withKids); for (@Clients) { print $_ $line; } last if (!$n--); } close(SP); exit; sub spawn { my $S = shift; my $pid; if (!defined($pid = fork)) { print "cannot fork: $!"; return; } elsif ($pid) { print " I'm the Server-Parent: pid:$pid \$\$:$$\n"; return; # I'm the parent } $S->waitNewConn(1); # yes with Kids, of course => (1) exit; } # end sub spawn