Abstraindo tudo que tem ai de perl.<div>Eu lembro que quando mexia com sockts no Delphi, pra mandar uma mensagem para o cliente, eu precisa saber qual é o cliente.</div><div>Então eu tinha uma array (no perl vc pode fazer um hash +D) todos os clientes, ai depois era só acessar o objeto e chamar um metodo send.</div>
<div><br></div><div>Mas acho que o e-mail do solli abaixo (que chegou enquanto escrevia) tem beem mais detalhes!</div><div><br><div class="gmail_quote">2011/5/3 Stanislaw Pusep <span dir="ltr"><<a href="mailto:creaktive@gmail.com">creaktive@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Yaih Carneiro!<div>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.</div>
<div>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</div>
<div>Veja um servidor HTTPD toscão que aguenta 100 conexões simultâneas sem apelar p/load descomunal:</div><div><br></div><div><a href="https://gist.github.com/781246" target="_blank">https://gist.github.com/781246</a><br clear="all">
<br>ABS()<br><br>
<br><br><div class="gmail_quote"><div><div></div><div class="h5">2011/5/3 Andre Carneiro <span dir="ltr"><<a href="mailto:andregarciacarneiro@gmail.com" target="_blank">andregarciacarneiro@gmail.com</a>></span><br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div></div><div class="h5">
Salve Monges!<div><br></div><div><br></div><div>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:</div>
<div><br></div><div>- O 'socket' do lado do 'client' escreve coisas no socket </div><div>- O 'socket' do lado do server lê coisas do Socket;</div><div><br></div><div>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:</div>
<div><br></div><div><br></div><div>SERVER: </div><div><br></div><div><code></div><div>use strict;</div><div>use warnings;</div><div>use IO::Socket::INET</div><div>use Daemon::Generic;</div><div>use feature qw/ say switch /;</div>
<div>.</div><div>.</div><div>.</div><div>#configuração</div><div>.</div><div>.</div><div>.</div><div><div> my $usock = IO::Socket::INET->new ( </div><div> Type<span style="white-space:pre-wrap"> </span>=> SOCK_STREAM ,</div>
<div> LocalAddr<span style="white-space:pre-wrap"> </span>=> $config_socket->{ SocketBind },</div><div> LocalPort<span style="white-space:pre-wrap"> </span>=> $config_socket->{ SocketPort },</div>
<div> Proto<span style="white-space:pre-wrap"> </span>=> 'tcp',</div><div> Listen<span style="white-space:pre-wrap"> </span>=> 1,</div>
<div> ReuseAddr<span style="white-space:pre-wrap"> </span>=> 1,</div><div><span style="white-space:pre-wrap"> </span> ) or die $!;</div></div>
<div><br></div><div><br></div><div> my $pid = fork;</div><div> if(!defined($pid)){</div><div> say "FATAL! Sem recursos para o fork! Abortando!";</div><div> exit 0;</div><div> }</div><div>
elsif($pid == 0){</div>
<div> my $newconn = &get_conn(); </div><div> while(1){</div><div> #uma 'pá' de coisa aqui no child...</div><div> sleep 60;</div><div> }</div><div> exit(1);</div>
<div> }</div><div> else {</div><div> my $r = undef;</div><div> while(1){</div><div> say "I'm working!";</div><div> if( $r = $usock->accept ){</div><div> &process_commands($r, \$usock);</div>
<div> }</div><div> else {</div><div> $logerr->write('error','Problemas com o socket! Abortando!' . $!);</div><div> exit(0);</div><div> }</div>
<div> sleep 1;</div><div> }</div><div># $usock->close;</div><div> close $out;</div><div><br></div><div> waitpid($pid,0);</div><div> }</div><div><br></div><div><br></div><div><br>
</div><div><div>sub process_commands {</div><div> my $sh = shift;</div><div> my $rsock = shift;</div><div> my $res = 0;</div><div> while(<$sh>){</div><div> #tratando o que vem do client</div><div>
my $out = $_ || 'none';</div><div> $out =~ s/^(\ |\t)+//;</div><div> my @params = split /\ +/, $out;</div><div> my ($command,$parameter) = ( $params[0],$params[1] );</div><div> #separando algumas informações</div>
<div> my %client_auth_data = ( host => undef,</div><div> user => undef,</div><div> password => undef,</div><div> port => undef,</div>
<div> );</div><div><br></div><div> #Implementar a camada de autenticação aqui.</div><div><br></div><div> given($command){</div><div> when( 'stopsafe' ){</div><div> say 'Executando o stopsafe';</div>
<div> if(!&pause_MTAs()){</div><div> #enviar mensagem de erro via socket </div><div> }</div><div> else {</div><div> #enviar mensagem de ok para o socket...</div>
<div> } </div><div><br></div><div> $res = 1;</div><div> }</div><div> #mais uma pancada de comandos aqui...</div><div> default {</div><div> my $msg = "Comando inválido! '$command $parameter' ";</div>
<div> }</div><div> }</div><div> }</div><div> return $res;</div><div>}</div></div><div><br></div><div><br></div><div><br></div><div></code></div><div><br></div><div><br></div><div>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.</div>
<div><br></div><div><br></div><div><br></div><div>CLIENT</div><div><br></div><div><code></div><div> use strict;</div><div> use warnings;</div><div> use IO::Socket::INET;</div><div> .</div><div> .</div>
<div> .</div><div><br></div><div><div> my ($bind, $port ) = @_;</div><div> my $sock = IO::Socket::INET->new ( </div><div> PeerAddr<span style="white-space:pre-wrap"> </span>=> $bind,</div>
<div> PeerPort<span style="white-space:pre-wrap"> </span>=> $port,</div><div> Proto<span style="white-space:pre-wrap"> </span>=> 'tcp',</div>
<div> Blocking => 0,</div><div> ReuseAddr => 1,</div><div> ) or die $!;</div><div> </div><div> $sock->send('chave1 valor1 chave2 valor2');</div>
<div><br></div><div> while(<$sock>){</div><div><span style="white-space:pre-wrap"> </span>#Teoricamente deveria ter alguma coisa no socket, mas nao rola...</div><div> }</div><div><br></div><div>
$sock->close();</div></div><div><br></div><div><br></div><div></code></div><div><br></div><div><br></div><div>Perguntas:</div><div><br></div><div><br></div><div>- Como gravar no socket do lado do server, de modo que isso seja legível do lado do client?</div>
<div>- Preciso de protocolo específico para fazer isso ?</div><div>- 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?</div>
<div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>Cheers!</div><div><br></div><font color="#888888"><div><br></div><div><br clear="all"><br>-- <br>André Garcia Carneiro<br>
Analista/Desenvolvedor Perl<br>
(11)82907780<br>
</div>
</font><br></div></div>=begin disclaimer<br>
Sao Paulo Perl Mongers: <a href="http://sao-paulo.pm.org/" target="_blank">http://sao-paulo.pm.org/</a><br>
SaoPaulo-pm mailing list: <a href="mailto:SaoPaulo-pm@pm.org" target="_blank">SaoPaulo-pm@pm.org</a><br>
L<<a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a>><br>
=end disclaimer<br>
<br></blockquote></div><br></div>
<br>=begin disclaimer<br>
Sao Paulo Perl Mongers: <a href="http://sao-paulo.pm.org/" target="_blank">http://sao-paulo.pm.org/</a><br>
SaoPaulo-pm mailing list: <a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
L<<a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a>><br>
=end disclaimer<br>
<br></blockquote></div><br><br clear="all"><br>-- <br>Renato Santos<br><a href="http://www.renatocron.com/blog/" target="_blank">http://www.renatocron.com/blog/</a><br>
</div>