[PERL] Lecture bufferisé sur socket

Lecture bufferisé sur socket [PERL] - Perl - Programmation

Marsh Posté le 02-09-2008 à 14:44:25    

Bonjour,
 
Alors voila le problème, je dois lire un flux de bit et le décoder afin de traduire les informations envoyées (selon une norme définie) pour ensuite les stoquer dans une base de donnée.
 
Jusque la tout va bien, j'ai fait mon programme qui décode les champs envoyés pas le serveur et les convertis.
Le problème est la lecture se fait bit par bit via la fonction sysread() et que je voudrais maintenant pouvoir bufferiser ma lecture afin d'optimiser l'opperation.
 
Je met donc toutes mes donnée dans un buffer (en faisant un sysread plus gros), mais ensuite je n'arrive pas a accéder a une adresse précise de ce buffer. Étant débutant en perl, j'ai des problèmes avec la logique de typage et d'allocation memoire du langage.
 
Pourriez vous m'aider sur ce point, en clair, comment peut ont faire pour stocker des données dans un buffer et ensuite accéder a un segment (une adresse) particulier(e) du buffer en perl ?
 
Merci  :)

Reply

Marsh Posté le 02-09-2008 à 14:44:25   

Reply

Marsh Posté le 02-09-2008 à 17:14:54    

Si tu nous montrais ce que tu fais comme appel avec le "gros" sysread, et ce que tu essayes de faire pour "acceder" à une adresse précise dans le buffer, on pourrait peut être t'aider.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 03-09-2008 à 07:23:43    

yum_yum a écrit :

Bonjour,
 
Alors voila le problème, je dois lire un flux de bit et le décoder afin de traduire les informations envoyées (selon une norme définie) pour ensuite les stoquer dans une base de donnée.
 
Jusque la tout va bien, j'ai fait mon programme qui décode les champs envoyés pas le serveur et les convertis.
Le problème est la lecture se fait bit par bit via la fonction sysread() et que je voudrais maintenant pouvoir bufferiser ma lecture afin d'optimiser l'opperation.

bit à bit pas possible. Remplace ton sysread par des read et magique, c'est bufferisé !

Reply

Marsh Posté le 03-09-2008 à 08:42:56    

Merci pour vos reponses !
 

Code :
  1. sysread( $fd, $tmp, $BUF_SIZE );


 
Voila comment je fait, le résultat de la lecture est donc stoque dans $tmp, qui a vrai dire n'ai pas de type particulier d'où les problèmes d'accès (si ça avais été un tableau ou une string ce serait beaucoup plus clair  :)  )
Quand a remplacer le sysread par un read, cela ne marche pas j'ai toujours le même problème d'accès, de plus j'ai lu qu'il était déconseiller d'utiliser read pour lire sur des sockets.
 

Reply

Marsh Posté le 03-09-2008 à 09:39:18    

Normalement, ton $tmp est une string dans laquelle les données ont été écrites sous forme d'octets, il me semble.
Donc pour acceder a un bit précis, il va falloir que tu détermines (division par 8) l'octet ou il se trouve, puis que tu testes avec un masque pour récupérer la valeur du bit.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 03-09-2008 à 09:42:57    

Mais bon, si c'est pour lire une socket, pourquoi reiventer la roue:  
   

Citation :

use IO::Socket;    
my $sock = IO::Socket::INET->new('some_server');
$sock->read($data, 1024);


Ou quelque chose de ce genre devrait te convenir, non?
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 03-09-2008 à 14:24:09    

En fait c'est avec le $data récupéré que j'ai des problèmes, comme c'est une string, je fait des substr pour la découper, et le résultat obtenu est aléatoire, parfois cela me sort 1 caractère, parfois 2 ...
Il y a t il une autre méthode pour récupérer des morceau de string ?

Reply

Marsh Posté le 03-09-2008 à 15:33:17    

Si j'ai bien compris, ton $data est un bit vector, ie une suite de bits a 0 ou 1.
Tu peux alors faire ceci:
@bits = split(//, unpack("b*", $data));
Et @bits est alors un array de valeurs a 0 ou 1.
Note que la fonction unpack va a priori faire du padding sur $data avec des bits finaux a zero pour avoir un alignement sur un octet.
Si tu sais exactement le nombre de bits qu'il y a dans tes données, 37 par exemple, tu peux remplacer le "b*" par "b37".
A+,


Message édité par gilou le 03-09-2008 à 15:43:23

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-09-2008 à 09:11:27    

Merci Gilou,ca m'a l'air d'être bon :).
Du coup je me deamnde si cela vaut le coup de ne plus faire des sysread de 1, sachant que maintenant je fait une conversion en tableau :-/.

Reply

Marsh Posté le 04-09-2008 à 12:31:21    

Euh, une conversion en un tableau Perl, c'est une manip standard perl, donc efficace et peu couteuse.
Une floppée de sysread successifs, par contre, ca risque d'être un peu plus couteux en perfs, non?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-09-2008 à 12:31:21   

Reply

Marsh Posté le 04-09-2008 à 12:38:07    

Notes aussi que si tu ne veux pas passer par un tableau, perl a une fonction built in vec qui accede au bits d'un bit vector.
Tu pourrais donc dans ton cas tester le x-ie bit de ton $data comme $bit = vec($data,$x,1).
Mais je ne suis pas sur que ca soit plus efficace que le fait de passer par un tableau.
Y'a aussi, pour info, des modules Bit::Vector et Bit::Vector::String, mais je ne pense pas qu'ils te soient utiles.
A+,


Message édité par gilou le 04-09-2008 à 12:59:28

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed