[SP-pm] Separar o primeiro do resto

Stanislaw Pusep creaktive at gmail.com
Wed May 1 16:34:44 PDT 2013


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).

среда, 1 мая 2013 г. пользователь Tiago Peczenyj писал:

> Agora sim
>
> Bom, deixem me explicar o que eu quero fazer: o Riak tem uma interface que
> usa Protocol Buffers. por exemplo
>
>
> 0x14,0,0,0,0xa,0xa,0x11,0xa,0xf,0x7b,0x20,0x66,0x6f,0x6f,0x20,0x3d,0x3e,0x20,0x27,0x62,0x61,0x72,0x27,0x7d
>
> essa tralha toda representa uma resposta de um "GET", basicamente temos
>
> 4 bytes para o tamanho da mensagem
> resto da mensagem
>
> o resto da mensagem tem
>
> 1 byte para o codigo de retorno (em caso de erro é 0)
> o resto para ser decodificado via protocol buffers.
>
> logo temos
>
> 0x14,0,0,0|0xa|0xa,0x11,0xa,0xf,0x7b,0x20 ..
>     size | code | message
>
> então eu preciso fazer o seguinte
>
> ler os primeiros 4 bytes para saber o tamanho da mensagem
> ler o quinto byte para saber o codigo de retorno
> ler do sexto em diante para decodificar.
>
> basicamente um
>
> $socket->sysread($len, 4); # leio os 4 primeiros bytes
> my $len = unpack('L', $len); # converto pra inteiro 32 bits
>
> socket->sysread($buff, $len) # leio o resto
>
> my($code, $encoded_message) = unpack('c a*', $buff);
>
> E tudo aparentemente funciona. Eu estava fazendo 3 sysread's só para pegar
> toda a mensagem.
>
> 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:
>
> my ($len, $code, $msg) = unpack('L c a*', $msg);
>
> if ( bytes::lenght($code . $msg) == $len) {
>   # decode message
>  } else {
>   # read more bytes
>  }
> }
>
> 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
>
> sysread($buffer, 2048); # ou qq numero "grandão"
>
> 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.
>
> 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 ...
>
> Desculpem o email confuso.
>
> Tiago
>
>
>
>
>
>
>
> 2013/4/30 Stanislaw Pusep <creaktive em gmail.com>
>
> $ perl -E 'say for unpack "a a*", "hello"'
> h
> ello
> $
>
>
> ABS()
>
>
> 2013/4/30 Tiago Peczenyj <tiago.peczenyj em gmail.com>
>
> Nao posso resolver com unpack ???
> Em 30/04/2013 19:51, "Lucas Moraes" <lucastiagodemoraes em gmail.com>
> escreveu:
>
>  Só muda a expressão
> m{^([\d\w]{1})(.*?)}s
> $1 $2
>
>
> Em 30 de abril de 2013 19:46, Tiago Peczenyj <tiago.peczenyj em gmail.com>escreveu:
>
> Bytes!
>
> Na verdade eh algo como
>
> 09 00 AF 1D..
> Em 30/04/2013 19:41, "Lucas Moraes" <lucastiagodemoraes em gmail.com>
> escreveu:
>
>  com regex você faz isso
> m{(\d{1})(\d{1,})}s;
> $1, $2
>
>
> Em 30 de abril de 2013 19:37, Tiago Peczenyj <tiago.peczenyj em gmail.com>escreveu:
>
> Seguinte: tenho X bytes como
>
> $x="12345"
>
> E quero pegar o primeiro e o resto:
>
> ($a,$b) = magica $x;
>
> $a = 1
> $b = 2345
>
> Comofas?
>
> Eu posso fazer bytes::substr 2 vezes mas ta feio...
>
> =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
>
>
>
> =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
>
>
> =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
>
>
>
> =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
>
> --
> Tiago B. Peczenyj
> Linux User #405772
>
> http://about.me/peczenyj
>


-- 

ABS()
-------------- Pr�xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130501/2b3106f2/attachment.html>


More information about the SaoPaulo-pm mailing list