Epa, 4 bytes para armazenar o tamanho da mensagem?! Isso sugere que o protocolo pressupõe a leitura em chunks. O jeito eficiente seria ler em blocos de, digamos, 4KB, e tratar o 1o bloco da forma diferenciada. Isso é, lê o primeiro bloco, pega o tamanho da mensagem e o status, e armazena no buffer o "resto". Depois, continua lendo e concatenando. Bons exemplos disso você encontra na documentação do AnyEvent::Handle (ser ou não ser assíncrono é irrelevante; é que essa documentação em especial entra em detalhes bem desse nível).<span></span><br>
<br>среда, 1 мая 2013 г. пользователь Tiago Peczenyj  писал:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Agora sim<div><br></div><div>Bom, deixem me explicar o que eu quero fazer: o Riak tem uma interface que usa Protocol Buffers. por exemplo</div>
<div><br></div><div>0x14,0,0,0,0xa,0xa,0x11,0xa,0xf,0x7b,0x20,0x66,0x6f,0x6f,0x20,0x3d,0x3e,0x20,0x27,0x62,0x61,0x72,0x27,0x7d<br>

</div><div><br></div><div>essa tralha toda representa uma resposta de um "GET", basicamente temos </div><div><br></div><div>4 bytes para o tamanho da mensagem</div><div>resto da mensagem</div>

<div><br></div><div>o resto da mensagem tem</div><div><br></div><div>1 byte para o codigo de retorno (em caso de erro é 0)</div><div>o resto para ser decodificado via protocol buffers.</div>
<div>
<br></div><div>logo temos</div><div><br></div><div>0x14,0,0,0|0xa|0xa,0x11,0xa,0xf,0x7b,0x20 ..<br></div><div>    size | code | message</div><div><br></div><div>então eu preciso fazer o seguinte</div>

<div><br></div><div>ler os primeiros 4 bytes para saber o tamanho da mensagem</div><div>ler o quinto byte para saber o codigo de retorno</div><div>ler do sexto em diante para decodificar.</div><div>

<br></div><div>basicamente um</div><div><br></div><div>$socket->sysread($len, 4); # leio os 4 primeiros bytes</div><div>my $len = unpack('L', $len); # converto pra inteiro 32 bits</div>
<div>
<br></div><div>socket->sysread($buff, $len) # leio o resto</div><div class="gmail_extra"><br></div><div class="gmail_extra">my($code, $encoded_message) = unpack('c a*', $buff);</div><div class="gmail_extra">

<br></div><div class="gmail_extra">E tudo aparentemente funciona. Eu estava fazendo 3 sysread's só para pegar toda a mensagem.</div><div class="gmail_extra"><br></div><div class="gmail_extra">porem eu não sei se estou fazendo isso da forma mais eficiente. Na real eu poderia ler até 1024 bytes (por exemplo) e fazer unpack de tudo:</div>


<div class="gmail_extra"><br></div><div class="gmail_extra">my ($len, $code, $msg) = unpack('L c a*', $msg);<br><br>if ( bytes::lenght($code . $msg) == $len) {</div><div class="gmail_extra">  # decode message </div>


<div class="gmail_extra"> } else {</div><div class="gmail_extra">  # read more bytes</div><div class="gmail_extra"> }</div><div class="gmail_extra">}<br><br>Eu realmente não sei o que é melhor. Por um lado ler 2 vezes me garante que eu vou passar um numero mais exato para o sysread, por outro eu não sei qual é o impacto de fazer um </div>


<div class="gmail_extra"><br></div><div class="gmail_extra">sysread($buffer, 2048); # ou qq numero "grandão"</div><div class="gmail_extra"><br></div><div class="gmail_extra">sendo que a mensagem teve uns 20 bytes. meu medo é que isso "trave", independente do tamanho que eu estou "chutando". e como estou testando com um riak local eu estou eliminando varios problemas de rede.</div>


<div class="gmail_extra"><br></div><div class="gmail_extra">ALIAS qual a melhor maneira de implementar um timeout nessa operação de leitura? Tipo em 0.2 segundos se não veio nada quero que retorne undef e bola pra frente. Acho que vou ter que apelar para alarm do Time::HiRes ...</div>


<div class="gmail_extra"><br></div><div class="gmail_extra">Desculpem o email confuso.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Tiago</div><div class="gmail_extra"><br>

</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">

<br><div>2013/4/30 Stanislaw Pusep <span dir="ltr"><<a>creaktive@gmail.com</a>></span><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<div dir="ltr"><div>$ perl -E 'say for unpack "a a*", "hello"'</div><div>h</div><div>ello</div><div>$</div></div><div><br clear="all"><div><br>ABS()<br></div><div><div>


<br><br><div>2013/4/30 Tiago Peczenyj <span dir="ltr"><<a>tiago.peczenyj@gmail.com</a>></span><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">




<p>Nao posso resolver com unpack ???</p>
<div>Em 30/04/2013 19:51, "Lucas Moraes" <<a>lucastiagodemoraes@gmail.com</a>> escreveu:<div><div><br type="attribution">

<blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr">Só muda a expressão<div>m{^([\d\w]{1})(.*?)}s</div><div>$1 $2</div></div><div><br><br><div>Em 30 de abril de 2013 19:46, Tiago Peczenyj <span dir="ltr"><<a>tiago.peczenyj@gmail.com</a>></span> escreveu:<br>






<blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><p>Bytes!</p>
<p>Na verdade eh algo como</p>
<p>09 00 AF 1D..</p>
<div>Em 30/04/2013 19:41, "Lucas Moraes" <<a>lucastiagodemoraes@gmail.com</a>> escreveu:<div><div><br type="attribution">
<blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr">com regex você faz isso<div>m{(\d{1})(\d{1,})}s;</div><div>$1, $2</div></div><div><br><br><div>Em 30 de abril de 2013 19:37, Tiago Peczenyj <span dir="ltr"><<a>tiago.peczenyj@gmail.com</a>></span> escreveu:<br>








<blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><p>Seguinte: tenho X bytes como</p>
<p>$x="12345"</p>
<p>E quero pegar o primeiro e o resto:</p>
<p>($a,$b) = magica $x;</p>
<p>$a = 1<br>
$b = 2345</p>
<p>Comofas?</p>
<p>Eu posso fazer bytes::substr 2 vezes mas ta feio...</p>
<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>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>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></div></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>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>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>
</blockquote></div></div></div></blockquote></div></div></div></div></blockquote></div>-- <br>Tiago B. Peczenyj<br>Linux User #405772<br><br><a href="http://about.me/peczenyj" target="_blank">http://about.me/peczenyj</a>
</div></div>
</blockquote><br><br>-- <br><br>ABS()<br><br>