summaryrefslogtreecommitdiff
path: root/i/marvin
diff options
context:
space:
mode:
authorhaller2006-04-21 01:01:37 +0000
committerhaller2006-04-21 01:01:37 +0000
commitcc67b62122a3e26a22c1273e69546ef2f81e974d (patch)
tree505ef245a8f3ea70679772b7c90bd1e7c82da301 /i/marvin
parent77345d83565b00b825e95730d3a9527364d5be5d (diff)
* 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)
Diffstat (limited to 'i/marvin')
-rw-r--r--i/marvin/src/Makefile.defs2
-rw-r--r--i/marvin/src/socket/Makefile.defs14
-rw-r--r--i/marvin/src/socket/socket_databuffer.cc70
-rw-r--r--i/marvin/src/socket/socket_databuffer.hh11
-rw-r--r--i/marvin/src/socket/socket_server.cc4
-rw-r--r--i/marvin/src/socket/test_socket_databuffer.cc125
-rw-r--r--i/marvin/src/socket/test_socket_old.cc (renamed from i/marvin/src/socket/test_socket.cc)0
7 files changed, 187 insertions, 39 deletions
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: <nicolas@boiteameuh.org>
// }}}
-#include "socket_databuffer.h"
+#include "socket_databuffer.hh"
+
+#include <stdexcept>
+#include <iostream>
// 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<unsigned>(strBuffer_[0]) << 24
+ | static_cast<unsigned>(strBuffer_[1]) << 16
+ | static_cast<unsigned>(strBuffer_[2]) << 8
+ | static_cast<unsigned>(strBuffer_[3]);
+ // On regarde si on a suffisemment de données pour constituer le DB
+ if(dbSize_ <= strBuffer_.size() - 4)
+ {
+ dbBuffer_.write(reinterpret_cast<const uint8_t *>(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<const char *>(&dbSize)), sizeof(unsigned));
+ char entete[4];
+ entete[0] = static_cast<char> (dbSize >> 24);
+ entete[1] = static_cast<char> (dbSize >> 16);
+ entete[2] = static_cast<char> (dbSize >> 8);
+ entete[3] = static_cast<char> (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<const char *>(donnees), dbSize));
+ SocketClient::write(std::string(reinterpret_cast<const char *>(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: <nicolas@boiteameuh.org>
// }}}
+#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 <sys/socket.h>
#include <cerrno>
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 <iostream>
+#include <sys/wait.h>
+
+//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<const uint8_t *>(strDepart.c_str()),
+ strDepart.size());
+ db1.write(reinterpret_cast<const uint8_t *>(&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.cc b/i/marvin/src/socket/test_socket_old.cc
index f2beb51..f2beb51 100644
--- a/i/marvin/src/socket/test_socket.cc
+++ b/i/marvin/src/socket/test_socket_old.cc