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

I made script that opens a socket server on port 2345. This script runs like a cgi (from apache). The problem is, I can't connect from out side to the port 2345! I already made some script like that, but the only difference was that now I made with the module IO::Socket, and before just Socket.

Some one know way a socket server from IO::Socket doesn't accept external connections and a normal Socket does?! Or there is a way to enable external users on IO::Socket?

This problems was tested on Linux and Win32, and are not a problem with Firewall!

Here are 2 simples scripts to show that:

IO::Socket, that doesn't accept external connections:

#!/usr/bin/perl use IO::Socket; my $server = IO::Socket::INET->new( Listen => 5, LocalAddr => 'localhost', LocalPort => 2345, Proto => 'tcp' ) ; my $client = $server->accept; while (<$client>) { print $_ ;} exit;

Pure Socket, that is OK:

#!/usr/bin/perl sub SOCKET_init { # Creat the socket for the server: $| = 1 ; use Socket;my $p=getprotobyname('tcp');socket(SRV,PF_INET,S +OCK_STREAM,$p); setsockopt(SRV,SOL_SOCKET,SO_REUSEADDR,pack('l',1));my($opn,$try); while($opn!=1 && $try<=20){if(bind(SRV,sockaddr_in($_[0],INADDR_ANY) +)){$opn=1} else{$try++;sleep(1)}}if($opn!=1){print"ERROR! Port $_[0] in use.\n" +;exit} listen(SRV,SOMAXCONN);my($wpid,$pad)=(0);$SIG{CHLD}=\&REAPER;my $CLT +; for($wpid=0;&ACT_CLT;$wpid=0,close(NS)) {next if $wpid and not $pad; +my($p,$a)=sockaddr_in($pad); my @i=unpack('C4',$a);$CLT++;$PORTS{$CLT}=$p;$IPS{$CLT}=join('.',@i) +;my $sl=select(NS);$|=1; select($sl);if($_[1]=~/^(1|ye?s?|si?m?)$/i){&SPAWN($CLT)}else{&Serve +r_DO($CLT)}} sub REAPER{$wpid=wait;$SIG{CHLD}=\&REAPER} sub ACT_CLT{return($pad=a +ccept(NS,SRV)) || $wpid} ## Fork to accept other connections while connected with client: (no +t gruped for you modify) sub SPAWN { my ( $CLIENT_id ) = @_ ; my $pid ; if (!defined($pid = fork)) { print "cannot fork: $!\n" ; return ;} elsif ($pid) { return ;} exit &Server_DO($CLIENT_id) ; } } &SOCKET_init(2345) ; sub Server_DO { my ( $CLIENT_id ) = @_ ; print "New Client!\n" ; while( my $buf = <NS> ) { print $buf ; } close(NS) ; exit; }

Graciliano M. P.
"The creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re: Servers on IO::Socket or just Socket?
by sauoq (Abbot) on Oct 23, 2002 at 03:08 UTC
    The problem is, I can't connect from out side to the port 2345!

    That's because you gave 'localhost' as your LocalAddr parameter. Try using the machine's hostname or the IP of the interface you want to use instead.

    -sauoq
    "My two cents aren't worth a dime.";
    
      Even better, don't use the LocalAddr option unless you need it. By default, IO::Socket::INET binds to all addresses on the machine. Then, you don't need to determine or hardcode the hostname or IP address and it will work on machines with multiple IP addresses. BTW, on both Windows and Unix, you can use the 'netstat' command to list the active outgoing and incoming sockets. Very useful to check if your program is listening on the port and address you expect.
      It works! Thanks! But in the pod this isn't documented very well. Some comment can be made...

      Graciliano M. P.
      "The creativity is the expression of the liberty".