par
Sékiltoyai » 26 juin 2009, 02:55
Tu mélanges ici allègrement deux problèmes. Et du coup ça devient difficile de savoir si même pour toi c'est clair. Il y a le problème de la récupération des données en hexadécimal d'une part, et le problème de la taille variable de l'autre.
Pour le problème de l'hexa, il y a des fonctions qui existent déjà pour transformer une chaine binaire en hexa. Par exemple bin2hex. Mais il y en a d'autres, tu chercheras. La preuve que cela marche :
Client :
<?php
if(!($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)))
{
echo "Erreur socket_create\n";
}
if(!socket_connect($sock, "localhost", 4))
{
echo "Erreur socket_connect\n";
}
$msg = NULL;
if(($size = socket_recv($sock, $msg, 4, 0)) <= -1)
{
echo "Erreur socket_read\n";
}
socket_close($sock);
echo "Size : " . $size . "\nData : " . bin2hex($msg) . "\n";
?>
Serveur :
Code : Tout sélectionner
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int sock, client;
struct sockaddr_in addr = {sizeof(struct sockaddr_in), AF_INET, htons(4), INADDR_ANY, {0,0,0,0,0,0,0,0}};
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
printf("Erreur socket : %d\n", errno);
return -2;
}
if(bind(sock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in)))
{
printf("Erreur bind : %d\n", errno);
return -3;
}
if(listen(sock,4))
{
printf("Erreur listen : %d\n", errno);
return -4;
}
struct sockaddr cl_addr;
socklen_t cl_len;
while((client = accept(sock, &cl_addr, &cl_len)) != -1)
{
printf(".\n");
char buffer[4] = {0xff, 0x20, 0x84, 0xac};
send(client, buffer, sizeof(char[4]), 0);
close(client);
}
printf("Erreur accept : %d\n", errno);
}
Il affiche :
Size : 4
Data : ff2084ac
Ce qui est strictement correct, et parfaitement exploitable moyennant quelques modifications supplémentaires. Tu parlais d'octets contenant plusieurs bits d'informations, tu dois aussi pouvoir travailler directement sur chacun des octets en utilisant ta chaine comme un tableau, et en utilisant les opérateurs de décalage.
Et il y a le second problème, celui de la taille. Est ce que tu peux décrire exactement le protocole entre le moment où le matériel ouvre la connexion TCP et le moment où il la ferme (Tu le fais sur une seule connexion, c'est le plus important). Par exemple tu disais qu'il envoyait son numéro de série, quand est-ce qu'il l'envoie ? Va-t-il envoyer plusieurs paquets sur une même connexion Plusieurs types de paquets ?
Sinon, je te rassure, ce que tu cherchais à faire (sniffer les paquets), ce n'est pas impossible, mais disons … hautement foireux pour être exact. C'est techniquement possible mais c'est vraiment une hérésie que de le faire (je pourrais sortir des dizaines et des dizaines d'arguments dans ce sens mais à vrai dire je ne juge pas cela utile…
Sinon, en effet, tu devrais faire le traitement en C (et ensuite éventuellement en effet le passer à un langage de script pour la mise à jour des données), c'est vraiment le langage le plus adapté. Un informaticien doit savoir évoluer. Si pour ce genre de projets là, tu le fais en PHP, il n'y aura aucun projet pour te faire évoluer…
Tu mélanges ici allègrement deux problèmes. Et du coup ça devient difficile de savoir si même pour toi c'est clair. Il y a le problème de la récupération des données en hexadécimal d'une part, et le problème de la taille variable de l'autre.
Pour le problème de l'hexa, il y a des fonctions qui existent déjà pour transformer une chaine binaire en hexa. Par exemple bin2hex. Mais il y en a d'autres, tu chercheras. La preuve que cela marche :
Client :
[php]
<?php
if(!($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)))
{
echo "Erreur socket_create\n";
}
if(!socket_connect($sock, "localhost", 4))
{
echo "Erreur socket_connect\n";
}
$msg = NULL;
if(($size = socket_recv($sock, $msg, 4, 0)) <= -1)
{
echo "Erreur socket_read\n";
}
socket_close($sock);
echo "Size : " . $size . "\nData : " . bin2hex($msg) . "\n";
?>
[/php]
Serveur :
[code]
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int sock, client;
struct sockaddr_in addr = {sizeof(struct sockaddr_in), AF_INET, htons(4), INADDR_ANY, {0,0,0,0,0,0,0,0}};
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
printf("Erreur socket : %d\n", errno);
return -2;
}
if(bind(sock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in)))
{
printf("Erreur bind : %d\n", errno);
return -3;
}
if(listen(sock,4))
{
printf("Erreur listen : %d\n", errno);
return -4;
}
struct sockaddr cl_addr;
socklen_t cl_len;
while((client = accept(sock, &cl_addr, &cl_len)) != -1)
{
printf(".\n");
char buffer[4] = {0xff, 0x20, 0x84, 0xac};
send(client, buffer, sizeof(char[4]), 0);
close(client);
}
printf("Erreur accept : %d\n", errno);
}
[/code]
Il affiche :
[quote="Résultat"]
Size : 4
Data : ff2084ac[/quote]
Ce qui est strictement correct, et parfaitement exploitable moyennant quelques modifications supplémentaires. Tu parlais d'octets contenant plusieurs bits d'informations, tu dois aussi pouvoir travailler directement sur chacun des octets en utilisant ta chaine comme un tableau, et en utilisant les opérateurs de décalage.
Et il y a le second problème, celui de la taille. Est ce que tu peux décrire exactement le protocole entre le moment où le matériel ouvre la connexion TCP et le moment où il la ferme (Tu le fais sur une seule connexion, c'est le plus important). Par exemple tu disais qu'il envoyait son numéro de série, quand est-ce qu'il l'envoie ? Va-t-il envoyer plusieurs paquets sur une même connexion Plusieurs types de paquets ?
Sinon, je te rassure, ce que tu cherchais à faire (sniffer les paquets), ce n'est pas impossible, mais disons … hautement foireux pour être exact. C'est techniquement possible mais c'est vraiment une hérésie que de le faire (je pourrais sortir des dizaines et des dizaines d'arguments dans ce sens mais à vrai dire je ne juge pas cela utile…
Sinon, en effet, tu devrais faire le traitement en C (et ensuite éventuellement en effet le passer à un langage de script pour la mise à jour des données), c'est vraiment le langage le plus adapté. Un informaticien doit savoir évoluer. Si pour ce genre de projets là, tu le fais en PHP, il n'y aura aucun projet pour te faire évoluer…