[SP-pm] Socket - algumas questões:

Stanislaw Pusep creaktive at gmail.com
Tue May 3 11:58:25 PDT 2011


Yaih Carneiro!
Que eu me lembre, accept() precisa retornar 2 sockets: accept(Client,
Server). Você pode, sim, ler e gravar no socket do client, mas no server
devem ser separados.
Um aviso: seu código terá sérios problemas de escalabilidade por causa do
fork(). E, como vc já deve prever, eu recomendaria o fabuloso AnyEvent :D
Veja um servidor HTTPD toscão que aguenta 100 conexões simultâneas sem
apelar p/load descomunal:

https://gist.github.com/781246

ABS()



2011/5/3 Andre Carneiro <andregarciacarneiro em gmail.com>

> Salve Monges!
>
>
> Estou com uns problemas com Sockets que mesmo fuçando bastante eu não
> consegui resolver. Os sockets tanto do lado do servidor quanto do lado do
> cliente estão ok, e isso significa:
>
> - O 'socket' do lado do 'client' escreve coisas no socket
> - O 'socket' do lado do server lê coisas do Socket;
>
> Agora eu preciso que o socket do lado do servidor envie os resultados como
> mensagens de erros e dados, de maneira geral, para o client. O que tá
> rolando agora:
>
>
> SERVER:
>
> <code>
> use strict;
> use warnings;
> use IO::Socket::INET
> use Daemon::Generic;
> use feature qw/ say switch /;
> .
> .
> .
> #configuração
> .
> .
> .
>     my $usock = IO::Socket::INET->new (
>                             Type => SOCK_STREAM ,
>                             LocalAddr => $config_socket->{ SocketBind },
>                             LocalPort => $config_socket->{ SocketPort },
>                             Proto => 'tcp',
>                             Listen => 1,
>                             ReuseAddr => 1,
>                 ) or die $!;
>
>
>   my $pid = fork;
>       if(!defined($pid)){
>         say "FATAL! Sem recursos para o fork! Abortando!";
>         exit 0;
>     }
>     elsif($pid == 0){
>         my $newconn = &get_conn();
>         while(1){
>             #uma 'pá' de coisa aqui no child...
>             sleep 60;
>         }
>         exit(1);
>     }
>     else {
>         my $r = undef;
>         while(1){
>             say "I'm working!";
>             if( $r = $usock->accept ){
>                 &process_commands($r, \$usock);
>             }
>             else {
>                 $logerr->write('error','Problemas com o socket! Abortando!'
> . $!);
>                 exit(0);
>             }
>             sleep 1;
>         }
> #        $usock->close;
>         close $out;
>
>         waitpid($pid,0);
>     }
>
>
>
> sub process_commands {
>     my $sh = shift;
>     my $rsock = shift;
>     my $res = 0;
>     while(<$sh>){
>         #tratando o que vem do client
>         my $out = $_ || 'none';
>         $out =~ s/^(\ |\t)+//;
>         my @params = split /\ +/, $out;
>         my ($command,$parameter) = ( $params[0],$params[1] );
>         #separando algumas informações
>         my %client_auth_data = (    host     => undef,
>                                     user     => undef,
>                                     password => undef,
>                                     port     => undef,
>                         );
>
>         #Implementar a camada de autenticação aqui.
>
>         given($command){
>             when( 'stopsafe' ){
>                 say 'Executando o stopsafe';
>                 if(!&pause_MTAs()){
>                          #enviar mensagem de erro via socket
>                 }
>                 else {
>                          #enviar mensagem de ok para o socket...
>                 }
>
>                 $res = 1;
>             }
>             #mais uma pancada de comandos aqui...
>             default {
>                 my $msg = "Comando inválido! '$command $parameter' ";
>             }
>         }
>     }
>     return $res;
> }
>
>
>
> </code>
>
>
> Resumo: Eu tenho um processo que fica executando várias outras coisas, e um
> outro só para ficar escutando comando vindo do socket do lado do CLIENT! O
> que eu quero fazer, imagino eu, seria gravar alguma coisa no socket de
> dentro dessa função 'process_commands'. E de alguma forma ler isso do
> client.
>
>
>
> CLIENT
>
> <code>
>     use strict;
>     use warnings;
>     use IO::Socket::INET;
>     .
>     .
>     .
>
>     my ($bind, $port ) = @_;
>     my $sock = IO::Socket::INET->new (
>                                 PeerAddr => $bind,
>                                 PeerPort => $port,
>                                 Proto => 'tcp',
>                                 Blocking    => 0,
>                                 ReuseAddr   => 1,
>                         ) or die $!;
>
>     $sock->send('chave1 valor1 chave2 valor2');
>
>     while(<$sock>){
> #Teoricamente deveria ter alguma coisa no socket, mas nao rola...
>     }
>
>     $sock->close();
>
>
> </code>
>
>
> Perguntas:
>
>
> - Como gravar no socket do lado do server, de modo que isso seja legível do
> lado do client?
> - Preciso de protocolo específico para fazer isso ?
> - Eu vi algumas pessoas usando udp ao invés de tcp alegando aumento de
> performance, mas abrindo mão de vários quesitos de segurança dentre outros
> problemas. Confirma?
>
>
>
>
>
>
>
> Cheers!
>
>
>
>
> --
> André Garcia Carneiro
> Analista/Desenvolvedor Perl
> (11)82907780
>
> =begin disclaimer
>   Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>  SaoPaulo-pm mailing list: SaoPaulo-pm em pm.org
>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
>
-------------- Pr�xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20110503/06a270df/attachment-0001.html>


More information about the SaoPaulo-pm mailing list