From cc67b62122a3e26a22c1273e69546ef2f81e974d Mon Sep 17 00:00:00 2001 From: haller Date: Fri, 21 Apr 2006 01:01:37 +0000 Subject: * Codage de SocketDataBuffer terminé * Modification du Makefile.defs de socket/ pour integrer SocketDataBuffer * Modification du Makefile.defs de src/ pour integrer les socket(SUBDIRS) * Remplacement de test_socket.cc pour tester les nouvelles sockets (l'ancien est renommé en test_socket_old.cc) * Ajout d'un test_socket_databuffer.cc pour tester SocketDataBuffer(avec des fork) --- i/marvin/src/Makefile.defs | 2 +- i/marvin/src/socket/Makefile.defs | 14 ++- i/marvin/src/socket/socket_databuffer.cc | 70 +++++++++------ i/marvin/src/socket/socket_databuffer.hh | 11 ++- i/marvin/src/socket/socket_server.cc | 4 +- i/marvin/src/socket/test_socket.cc | 76 ---------------- i/marvin/src/socket/test_socket_databuffer.cc | 125 ++++++++++++++++++++++++++ i/marvin/src/socket/test_socket_old.cc | 76 ++++++++++++++++ 8 files changed, 263 insertions(+), 115 deletions(-) delete mode 100644 i/marvin/src/socket/test_socket.cc create mode 100644 i/marvin/src/socket/test_socket_databuffer.cc create mode 100644 i/marvin/src/socket/test_socket_old.cc (limited to 'i/marvin') diff --git a/i/marvin/src/Makefile.defs b/i/marvin/src/Makefile.defs index cec8951..20922f7 100644 --- a/i/marvin/src/Makefile.defs +++ b/i/marvin/src/Makefile.defs @@ -25,7 +25,7 @@ SUBDIRS = utils utils/meta \ log serial timer \ data scheduler \ proto asserv \ - motor + motor socket # Répertoire où placer les objets. OBJ_DIR := obj diff --git a/i/marvin/src/socket/Makefile.defs b/i/marvin/src/socket/Makefile.defs index b3a03cc..1ff9efc 100644 --- a/i/marvin/src/socket/Makefile.defs +++ b/i/marvin/src/socket/Makefile.defs @@ -1,6 +1,12 @@ -PROGRAMS += test_socket test_server +PROGRAMS += test_socket test_socket_databuffer #test_server -net_OBJECTS = address.o server_socket.o socket_text.o +socket_basic_OBJECTS = address.o socket_server.o socket_client.o +socket_databuffer_OBJECTS = socket_databuffer.o $(socket_basic_OBJECTS) \ + $(data_OBJECTS) -test_socket_OBJECTS = test_socket.o $(net_OBJECTS) $(data_OBJECTS) -test_server_OBJECTS = test_server.o $(net_OBJECTS) $(data_OBJECTS) $(image_OBJECTS) +test_socket_OBJECTS = test_socket.o $(socket_basic_OBJECTS) $(data_OBJECTS) +test_socket_databuffer_OBJECTS = test_socket_databuffer.o \ + $(socket_databuffer_OBJECTS) $(data_OBJECTS) \ + $(socket_basic_OBJECTS) +#test_server_OBJECTS = test_server.o $(net_OBJECTS) $(data_OBJECTS) \ + $(image_OBJECTS) diff --git a/i/marvin/src/socket/socket_databuffer.cc b/i/marvin/src/socket/socket_databuffer.cc index 241b8f3..1b4258c 100644 --- a/i/marvin/src/socket/socket_databuffer.cc +++ b/i/marvin/src/socket/socket_databuffer.cc @@ -21,63 +21,77 @@ // Web: http://perso.efrei.fr/~haller/ // Email: // }}} -#include "socket_databuffer.h" +#include "socket_databuffer.hh" + +#include +#include // Constructeur SocketDataBuffer::SocketDataBuffer(void) - :SocketClient(), isReceiving_(false), dbSize_(0) // TODO Ça sert à quelque chose où il le fait implicitement? + :SocketClient(), dbSize_(0) // TODO Ça sert à quelque chose où il le fait implicitement? { } // Constructeur accept SocketDataBuffer::SocketDataBuffer(SocketServer & socketServer) - :SocketClient(socketServer), isReceiving_(false), dbSize_(0) + :SocketClient(socketServer), dbSize_(0) { } // Récupère un DataBuffer +// false en valeur de retour avec bloquant = true est un motif de licenciement bool SocketDataBuffer::read(DataBuffer & dbReaded, bool bloquant) { - bool dbRecu; - if (!isReceiving_) + std::string strReceive; + do { - // On récupère les données du socket - dbRecu = read(buffer_, bloquant); - if(!dbRecu) - return false; - // On extrait la taille de la DB si possible - if(buffer_.size() < 4) - { - isReceiving_ = true; - return false; - } - else + SocketClient::read(strReceive, bloquant); + strBuffer_.append(strReceive); + // On regarde si on a assez de donnée pour regarder si on a une en-tête + if(strBuffer_.size() > sizeof(unsigned)) { - dbSize_ &= buffer_[0] << 24; - dbSize_ &= buffer_[1] << 16; - dbSize_ &= buffer_[2] << 8; - dbSize_ &= buffer_[3]; + dbSize_ = 0; + dbSize_ = static_cast(strBuffer_[0]) << 24 + | static_cast(strBuffer_[1]) << 16 + | static_cast(strBuffer_[2]) << 8 + | static_cast(strBuffer_[3]); + // On regarde si on a suffisemment de données pour constituer le DB + if(dbSize_ <= strBuffer_.size() - 4) + { + dbBuffer_.write(reinterpret_cast(strBuffer_.c_str() + 4) + , dbSize_); + dbReaded.swap(dbBuffer_); + dbBuffer_.clear(); + strBuffer_.erase(0, dbSize_ + 4); + return true; + } } - TODO - - + }while(bloquant); + return false; } // Ecrit un DB dans le socket void -SocketDataBuffer::write(const DataBuffer & db) +SocketDataBuffer::write(DataBuffer & db) { // On met une en-tête de 4 octects déterminant la taille de la DB unsigned dbSize = db.size(); - write(std::string(static_cast(&dbSize)), sizeof(unsigned)); + char entete[4]; + entete[0] = static_cast (dbSize >> 24); + entete[1] = static_cast (dbSize >> 16); + entete[2] = static_cast (dbSize >> 8); + entete[3] = static_cast (dbSize); + + SocketClient::write(std::string(entete,4)); // On récupère les données de la dataBuffer uint8_t * donnees = new uint8_t[dbSize]; db.read(donnees, dbSize); if (db.size() != 0) - throw std::runtime_exception("ERREUR DE CODAGE dans SocketDataBuffer" - "::Write"); + throw std::runtime_error("ERREUR DE CODAGE dans SocketDataBuffer" + "::Write"); // On envoie le tout et on nettoie l'allocation - write(std::string(static_cast(donnees), dbSize)); + SocketClient::write(std::string(reinterpret_cast(donnees), + dbSize)); delete [] donnees; } diff --git a/i/marvin/src/socket/socket_databuffer.hh b/i/marvin/src/socket/socket_databuffer.hh index e28c8cd..c385db5 100644 --- a/i/marvin/src/socket/socket_databuffer.hh +++ b/i/marvin/src/socket/socket_databuffer.hh @@ -24,17 +24,20 @@ // Email: // }}} +#include "socket_client.hh" +#include "data/data_buffer.hh" + /// Class s'occupant en particulier de récupérer les DataBuffer via le réseau /// TCP/IP class SocketDataBuffer : public SocketClient { private: - /// En cours de reception d'un DB - bool isReceiving_; /// Taille de la DB à recevoir unsigned dbSize_; /// Tampon provisoire - std::string buffer_; + std::string strBuffer_; + /// DataBuffer Provisoire + DataBuffer dbBuffer_; public: /// Constructeur SocketDataBuffer(void); @@ -43,7 +46,7 @@ class SocketDataBuffer : public SocketClient /// Récupère un DataBuffer bool read (DataBuffer & dbReaded, bool bloquant); /// Ecrit un DB dans le socket - void write (const DataBuffer & db); + void write (DataBuffer & db); }; #endif // socket_databuffer_hh diff --git a/i/marvin/src/socket/socket_server.cc b/i/marvin/src/socket/socket_server.cc index 6cb8798..1a9cdb9 100644 --- a/i/marvin/src/socket/socket_server.cc +++ b/i/marvin/src/socket/socket_server.cc @@ -23,9 +23,9 @@ * * }}} */ -#include "socket/socket_server.hh" +#include "socket_server.hh" #include "utils/errno_exception.hh" -#include "socket/address.hh" +#include "address.hh" #include #include diff --git a/i/marvin/src/socket/test_socket.cc b/i/marvin/src/socket/test_socket.cc deleted file mode 100644 index f2beb51..0000000 --- a/i/marvin/src/socket/test_socket.cc +++ /dev/null @@ -1,76 +0,0 @@ -// test_socket.cc -// robert - programme du robot 2005. {{{ -// -// Copyright (C) 2005 Dufour Jérémy -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// Contact : -// Web: %WEB% -// Email: -// }}} - -#include "server_socket.hh" -#include "address.hh" -#include "socket_text.hh" -#include "data/data_input_file.hh" -#include "data/data_buffer.hh" - -#include -#include -#include -#include -#include - -int -main (int argc, char **argv) -{ - if (argc == 4) - { - try - { - // Récupération des données du fichier - DataInputFile df (argv[3]); - std::vector img (319680); - df.read (&img[0], 319680); - // Ecriture des données du fichier dans le buffer - DataBuffer db (&img[0], img.size (), img.size (), - DataBuffer::Image); - DataBuffer dbAnswer; - // Création du socket - char *h = argv[1]; - SocketText st (Address (h, atoi (argv[2]))); - st.nonblock (); - st >> dbAnswer; - if (dbAnswer.type () == DataBuffer::AskImage) - { - // Envoie des données - st << db; - while (st.send () != 0); - } - } - catch (const std::runtime_error &r) - { - std::cerr << argv[0] << ": " << r.what () << std::endl; - return 1; - } - } - else - { - std::cerr << "Syntaxe: " << argv[0] << " host port in_file" << - std::endl; - return 1; - } -} diff --git a/i/marvin/src/socket/test_socket_databuffer.cc b/i/marvin/src/socket/test_socket_databuffer.cc new file mode 100644 index 0000000..f6f1a40 --- /dev/null +++ b/i/marvin/src/socket/test_socket_databuffer.cc @@ -0,0 +1,125 @@ +/* test_socket.cc - Programme de test des sockets. */ +/* Simulotron - Programme de simulation de robot {{{ + * + * Copyright (C) 2005 Nicolas Haller + * + * Robot APB Team/Efrei 2005. + * Web: http://assos.efrei.fr/robot/ + * Email: robot AT efrei DOT fr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "socket_server.hh" +#include "socket_databuffer.hh" +#include "data/data_buffer.hh" +#include "utils/errno_exception.hh" + +#include +#include + +//Chaine et char de test +const std::string strDepart = "J'aime la prog système."; +const char a = 'f'; +DataBuffer db1, db2; + +int testSockServ(SocketServer & sockServ); +int testSockClient(int pauseMode); + +int main(void) +{ + pid_t pid; + int resultServer = 0, resultClient; + // Pause mode pour débugger le fork + int pauseMode = 0; + + // Création de la socket serveur; + SocketServer sockServ(std::string(),4242); + // Mise en écoute du socket serveur + sockServ.listen(12); + + // on fork pour traiter le client et le serveur + pid = fork(); + if(pid == 0) //Processus fils + testSockClient(pauseMode); + else //Processus parent + resultServer = testSockServ(sockServ); + + // On analyse les résultats + wait(&resultClient); + if (!(WIFEXITED(resultClient) && WEXITSTATUS(resultClient) == 0)) + { + std::cerr << "ECHEC: Problème coté client" << std::endl; + exit (-1); + } + if (resultServer != 0) + { + std::cerr << "ECHEC: Problème coté serveur" << std::endl; + exit (-1); + } + + return 0; +} + +int testSockServ(SocketServer & sockServ) +{ + try + { + // On crée le DataBuffer + db1.write(reinterpret_cast(strDepart.c_str()), + strDepart.size()); + db1.write(reinterpret_cast(&a), sizeof(const char)); + // Acceptation d'une connection + SocketDataBuffer sockFork(sockServ); + // On écrit la DataBuffer dans la socket + sockFork.write(db1); + } + catch(errno_exception & chier) + { + std::cout << "CHIER !! Une exception a été lancé coté serveur!!" << std::endl; + std::cout << chier.what() << std::endl; + return 1; + } + return 0; +} + +int testSockClient(int pauseMode) +{ + // Chance pour debbuger le fork + while(pauseMode) + sleep(10); + try + { + // Création de la socket client + SocketDataBuffer sockDataBuffer; + // Demande de connection + sockDataBuffer.connect(std::string("127.0.0.1"), 4242); + // Reception du message serveur + sockDataBuffer.read(db2, true); + // Paye ta comparaison de DataBuffer + if(db1.size() != db2.size()) + { + std::cout << "CHIER!! Les DB ne font pas la même size" << std::endl; + exit (1); + } + } + catch(errno_exception & chier) + { + std::cout << "CHIER !! Une exception a été lancé coté client!!" << std::endl; + std::cout << chier.what() << std::endl; + exit (1); + } + exit (0); +} diff --git a/i/marvin/src/socket/test_socket_old.cc b/i/marvin/src/socket/test_socket_old.cc new file mode 100644 index 0000000..f2beb51 --- /dev/null +++ b/i/marvin/src/socket/test_socket_old.cc @@ -0,0 +1,76 @@ +// test_socket.cc +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Dufour Jérémy +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Contact : +// Web: %WEB% +// Email: +// }}} + +#include "server_socket.hh" +#include "address.hh" +#include "socket_text.hh" +#include "data/data_input_file.hh" +#include "data/data_buffer.hh" + +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + if (argc == 4) + { + try + { + // Récupération des données du fichier + DataInputFile df (argv[3]); + std::vector img (319680); + df.read (&img[0], 319680); + // Ecriture des données du fichier dans le buffer + DataBuffer db (&img[0], img.size (), img.size (), + DataBuffer::Image); + DataBuffer dbAnswer; + // Création du socket + char *h = argv[1]; + SocketText st (Address (h, atoi (argv[2]))); + st.nonblock (); + st >> dbAnswer; + if (dbAnswer.type () == DataBuffer::AskImage) + { + // Envoie des données + st << db; + while (st.send () != 0); + } + } + catch (const std::runtime_error &r) + { + std::cerr << argv[0] << ": " << r.what () << std::endl; + return 1; + } + } + else + { + std::cerr << "Syntaxe: " << argv[0] << " host port in_file" << + std::endl; + return 1; + } +} -- cgit v1.2.3