Accueil > > > BIBLIOTHÈQUE PERMETTANT D'UTILISER LES SOCKETS DE MANIÈRE TRANSPARENTE QU'ELLES SOIENT WINDOWS / UNIX ET TCP / UDP
BIBLIOTHÈQUE PERMETTANT D'UTILISER LES SOCKETS DE MANIÈRE TRANSPARENTE QU'ELLES SOIENT WINDOWS / UNIX ET TCP / UDP
Information sur la source
Description
Ce code c++ sans class permet d'utiliser des sockets compatibles Windows et UNIX. Sans avoir à ce soucier des différences de programmation entre une socket TCP et UDP. J'ai réaliser cette "bibliothèque" car je programme des sockets Windows et UNIX, TCP et UDP, et j'en avais marre d'avoir à changer le code à chaque fois, un simple #include "socket.hpp" et #define TCP ou UDP suffit maintenant. Un gain de temps et une portabilité non négligeable. Sous windows ne pas oublier de linker avec "libwsock32.a" N'hésitez pas à laisser des commentaires pour que je puisse améliorer mon code !
Source
- /*-------------SOCKET.HPP-------------*/
- // Socket library -*- C++ -*-
-
- // Copyright (C) 2006 Christophe Tournayre
- //
- // This library 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, or
- // (at your option) any later version.
-
- // This library 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.
-
- // As a special exception, you may use this file as part of a free software
- // library without restriction. Specifically, if other files instantiate
- // templates or use macros or inline functions from this file, or you compile
- // this file and link it with other files to produce an executable, this
- // file does not by itself cause the resulting executable to be covered by
- // the GNU General Public License. This exception does not however
- // invalidate any other reasons why the executable file might be covered by
- // the GNU General Public License.
-
-
- #ifndef __SOCKET_HPP__
- #define __SOCKET_HPP__
-
-
- // ********************************************************
- // Les includes
- // ********************************************************
- #if defined(WIN32)
- #include <winsock2.h> // pour les fonctions socket
- #else
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <linux/socket.h>
- #endif
-
- #include <string>
- #include <iostream> //Pour cout, cin, cerr
-
- // ********************************************************
- // Déclaration des structures et ENUM
- // ********************************************************
-
- enum Type {Udp, Tcp};
-
-
- // Structure pour l'inforamtion de la socket
- typedef struct
- {
- SOCKET id; // Déclaration de l'identifiant e la socket
- SOCKADDR_IN server; // Déclaration de la structure des informations lié au serveur
- } Sock;
-
-
- // Structure pour la fonction Recv (nb contient le nb de charactere recus, et c le charactere recu)
- typedef struct
- {
- int nb; // Nombre d'octets recus
- char c; // Charactere recu
- } Recv;
-
-
- Sock connect(char* address, int port, Type type);
- int send(Sock info, std::string mess, Type type);
- Recv recv(Sock info, Type type);
- int disconnect(Sock info, Type type);
-
-
- #endif
-
-
-
- /*-------------SOCKET.CPP-------------*/
-
- // Socket library -*- C++ -*-
-
- // Copyright (C) 2006 Christophe Tournayre
- //
- // This library 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, or
- // (at your option) any later version.
-
- // This library 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.
-
- // As a special exception, you may use this file as part of a free software
- // library without restriction. Specifically, if other files instantiate
- // templates or use macros or inline functions from this file, or you compile
- // this file and link it with other files to produce an executable, this
- // file does not by itself cause the resulting executable to be covered by
- // the GNU General Public License. This exception does not however
- // invalidate any other reasons why the executable file might be covered by
- // the GNU General Public License.
-
- #include "socket.hpp"
-
- using namespace std;
-
- Sock connect(char* address, int port, Type type)
- {
- // ********************************************************
- // Déclaration des variables
- // ********************************************************
- #if defined(WIN32)
- WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
- #endif
-
- Sock info;
- int erreur=0, nb; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
- string buffer; // Tampon contenant les données a envoyer
-
- #if defined(WIN32)
- // ********************************************************
- // Initialisation de Winsock
- // ********************************************************
- erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
-
- if (erreur!=0)
- {
- cerr << "Desole, je ne peux pas initialiser Winsock du a l'erreur : "<< erreur << " " << WSAGetLastError() << endl;
- throw(1);
- }
- else
- cout <<"WSAStartup : OK" << endl;
- #endif
-
- // ********************************************************
- // Ouverture d'une Socket
- // ********************************************************
- if(type==Tcp)
- info.id=socket(AF_INET,SOCK_STREAM,0);
-
- else
- info.id=socket(AF_INET,SOCK_DGRAM,0);
-
-
- if (info.id==INVALID_SOCKET)
- {
- cerr << "Desole, je ne peux pas creer la socket du a l'erreur : " << WSAGetLastError() << endl;
- throw(2);
- }
- else
- cout << "socket : OK" << endl;
-
- // ********************************************************
- // Ouverture de la session
- // ********************************************************
- info.server.sin_family=AF_INET;
- info.server.sin_addr.s_addr=inet_addr(address); // @ip serveur
- info.server.sin_port=htons(port); // Port écouté du serveur
-
- if(type==Tcp)
- {
- cout <<"connection en cours ";
-
- erreur=connect(info.id,(struct sockaddr*)&info.server,sizeof(info.server));
-
- if (erreur!=0)
- {
- cerr <<"Desole, je n'ai pas pu ouvrir la session TCP : " << erreur << " " << WSAGetLastError() << endl;
- throw(3);
- }
- else
- cout <<": OK" << endl;
- }
-
- return info;
- }
-
-
- int send(Sock info, string mess, Type type)
- {
- // ********************************************************
- // Déclaration des variables
- // ********************************************************
- int nb;
-
- // ********************************************************
- // Envoi des données
- // ********************************************************
- if (mess.size()>65535)
- {
- cerr << "Message trop long!" << endl;
- return -1;
- }
-
- if(type==Tcp)
- nb=send(info.id,mess.c_str(),mess.size(),0);
- else
- nb=sendto(info.id,mess.c_str(),mess.size(),0,(struct sockaddr*)&info.server,sizeof(info.server));
-
-
- if (nb==SOCKET_ERROR)
- {
- cerr << "Desole, je n'ai pas pu envoyer les donnees du a l'erreur : " << WSAGetLastError() << endl;
- return -2;
- }
- else
- {
- cout << "Requete HTTP : OK" << endl;
- return 0;
- }
- }
-
-
- Recv recv(Sock info, Type type)
- {
- Recv ret;
-
- if(type==Udp)
- {
- int temp=sizeof(info.server); // Passe par une variable afin d'utiliser un pointeur
- ret.nb=recvfrom(info.id,&ret.c,1,0,(struct sockaddr*)&info.server,&temp);
- }
- else
- ret.nb=recv(info.id,&ret.c,1,0);
-
-
- return ret;
- }
-
-
- int disconnect(Sock info, Type type)
- {
- // ********************************************************
- // Déclaration des variables
- // ********************************************************
- int erreur=0, ret=0;
-
- if(type==Tcp)
- {
- // ********************************************************
- // Fermeture de la session TCP Correspondant à la commande connect()
- // ********************************************************
- erreur=shutdown(info.id,2);
-
- if (erreur!=0)
- {
- cerr << "Desole, je ne peux pas fermer la session TCP du a l'erreur : " << erreur << " " << WSAGetLastError() << endl;
- ret = -1;
- }
- else
- cerr << "shutdown : OK" << endl;
- }
-
- // ********************************************************
- // Fermeture de la socket correspondant à la commande socket()
- // ********************************************************
- #if defined(WIN32)
- erreur=closesocket(info.id);
- #else
- erreur=close(info.id);
- #endif
-
- if (erreur!=0)
- {
- cerr << "Desole, je ne peux pas liberer la socket du a l'erreur : " << erreur << " " << WSAGetLastError() << endl;
- ret = -2;
- }
- else
- cout << "closesocket : OK" << endl;
-
-
- #if defined(WIN32)
- // ********************************************************
- // Quitte le winsock ouvert avec la commande WSAStartup
- // ********************************************************
- erreur=WSACleanup();
-
- if (erreur!=0)
- {
- cerr << "Desole, je ne peux pas liberer winsock du a l'erreur : " << erreur << " " <<WSAGetLastError() << endl;
- ret= -3;
- }
- else
- cout << "WSACleanup : OK" << endl;
- #endif
-
- return ret;
- }
-
-
-
-
-
-
- /*--------------MAIN.CPP--------------*/
-
- // Exemple d'utilisation de la bibliothèque
-
- #include <string>
- #include <iostream>
- #include "socket.hpp"
-
- using namespace std;
-
- int main ()
- {
- Sock info;
- Recv ret;
- int i = 0, val = 1024;
- string s, req("Donnees a envoyer");
-
- try
- {
- info=connect("172.0.0.1", 6666, Tcp);
- }
- catch (int tmp) // Traitement de l'exception
- {
- cerr << "Erreur dans la connexion" << endl;
- return tmp;
- }
-
-
- if(send(info, req, Tcp) !=0)
- {
- cerr << "Erreur lors de l'envoi de la requete : " << req << endl;
- disconnect(info, Tcp);
- return -4;
- }
-
-
- ret.nb=1;
-
- while(ret.nb>0 && i<=val)
- {
- ret=recv(info,Tcp);
-
- if (ret.nb==SOCKET_ERROR)
- {
- cerr << "ERREUR : Aucune données recue" << endl;
- disconnect(info, Tcp);
- retour= -2;
- }
-
- i++;
- s+=ret.c
- }
-
- cout << "Message recu :" << s << endl;
-
- if (disconnect(info, Tcp) != 0)
- {
- cerr << "Erreur lors de la deconnection !";
- return -3;
- }
-
- return 0;
- }
-
/*-------------SOCKET.HPP-------------*/
// Socket library -*- C++ -*-
// Copyright (C) 2006 Christophe Tournayre
//
// This library 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, or
// (at your option) any later version.
// This library 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.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#ifndef __SOCKET_HPP__
#define __SOCKET_HPP__
// ********************************************************
// Les includes
// ********************************************************
#if defined(WIN32)
#include <winsock2.h> // pour les fonctions socket
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/socket.h>
#endif
#include <string>
#include <iostream> //Pour cout, cin, cerr
// ********************************************************
// Déclaration des structures et ENUM
// ********************************************************
enum Type {Udp, Tcp};
// Structure pour l'inforamtion de la socket
typedef struct
{
SOCKET id; // Déclaration de l'identifiant e la socket
SOCKADDR_IN server; // Déclaration de la structure des informations lié au serveur
} Sock;
// Structure pour la fonction Recv (nb contient le nb de charactere recus, et c le charactere recu)
typedef struct
{
int nb; // Nombre d'octets recus
char c; // Charactere recu
} Recv;
Sock connect(char* address, int port, Type type);
int send(Sock info, std::string mess, Type type);
Recv recv(Sock info, Type type);
int disconnect(Sock info, Type type);
#endif
/*-------------SOCKET.CPP-------------*/
// Socket library -*- C++ -*-
// Copyright (C) 2006 Christophe Tournayre
//
// This library 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, or
// (at your option) any later version.
// This library 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.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include "socket.hpp"
using namespace std;
Sock connect(char* address, int port, Type type)
{
// ********************************************************
// Déclaration des variables
// ********************************************************
#if defined(WIN32)
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
#endif
Sock info;
int erreur=0, nb; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
string buffer; // Tampon contenant les données a envoyer
#if defined(WIN32)
// ********************************************************
// Initialisation de Winsock
// ********************************************************
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
if (erreur!=0)
{
cerr << "Desole, je ne peux pas initialiser Winsock du a l'erreur : "<< erreur << " " << WSAGetLastError() << endl;
throw(1);
}
else
cout <<"WSAStartup : OK" << endl;
#endif
// ********************************************************
// Ouverture d'une Socket
// ********************************************************
if(type==Tcp)
info.id=socket(AF_INET,SOCK_STREAM,0);
else
info.id=socket(AF_INET,SOCK_DGRAM,0);
if (info.id==INVALID_SOCKET)
{
cerr << "Desole, je ne peux pas creer la socket du a l'erreur : " << WSAGetLastError() << endl;
throw(2);
}
else
cout << "socket : OK" << endl;
// ********************************************************
// Ouverture de la session
// ********************************************************
info.server.sin_family=AF_INET;
info.server.sin_addr.s_addr=inet_addr(address); // @ip serveur
info.server.sin_port=htons(port); // Port écouté du serveur
if(type==Tcp)
{
cout <<"connection en cours ";
erreur=connect(info.id,(struct sockaddr*)&info.server,sizeof(info.server));
if (erreur!=0)
{
cerr <<"Desole, je n'ai pas pu ouvrir la session TCP : " << erreur << " " << WSAGetLastError() << endl;
throw(3);
}
else
cout <<": OK" << endl;
}
return info;
}
int send(Sock info, string mess, Type type)
{
// ********************************************************
// Déclaration des variables
// ********************************************************
int nb;
// ********************************************************
// Envoi des données
// ********************************************************
if (mess.size()>65535)
{
cerr << "Message trop long!" << endl;
return -1;
}
if(type==Tcp)
nb=send(info.id,mess.c_str(),mess.size(),0);
else
nb=sendto(info.id,mess.c_str(),mess.size(),0,(struct sockaddr*)&info.server,sizeof(info.server));
if (nb==SOCKET_ERROR)
{
cerr << "Desole, je n'ai pas pu envoyer les donnees du a l'erreur : " << WSAGetLastError() << endl;
return -2;
}
else
{
cout << "Requete HTTP : OK" << endl;
return 0;
}
}
Recv recv(Sock info, Type type)
{
Recv ret;
if(type==Udp)
{
int temp=sizeof(info.server); // Passe par une variable afin d'utiliser un pointeur
ret.nb=recvfrom(info.id,&ret.c,1,0,(struct sockaddr*)&info.server,&temp);
}
else
ret.nb=recv(info.id,&ret.c,1,0);
return ret;
}
int disconnect(Sock info, Type type)
{
// ********************************************************
// Déclaration des variables
// ********************************************************
int erreur=0, ret=0;
if(type==Tcp)
{
// ********************************************************
// Fermeture de la session TCP Correspondant à la commande connect()
// ********************************************************
erreur=shutdown(info.id,2);
if (erreur!=0)
{
cerr << "Desole, je ne peux pas fermer la session TCP du a l'erreur : " << erreur << " " << WSAGetLastError() << endl;
ret = -1;
}
else
cerr << "shutdown : OK" << endl;
}
// ********************************************************
// Fermeture de la socket correspondant à la commande socket()
// ********************************************************
#if defined(WIN32)
erreur=closesocket(info.id);
#else
erreur=close(info.id);
#endif
if (erreur!=0)
{
cerr << "Desole, je ne peux pas liberer la socket du a l'erreur : " << erreur << " " << WSAGetLastError() << endl;
ret = -2;
}
else
cout << "closesocket : OK" << endl;
#if defined(WIN32)
// ********************************************************
// Quitte le winsock ouvert avec la commande WSAStartup
// ********************************************************
erreur=WSACleanup();
if (erreur!=0)
{
cerr << "Desole, je ne peux pas liberer winsock du a l'erreur : " << erreur << " " <<WSAGetLastError() << endl;
ret= -3;
}
else
cout << "WSACleanup : OK" << endl;
#endif
return ret;
}
/*--------------MAIN.CPP--------------*/
// Exemple d'utilisation de la bibliothèque
#include <string>
#include <iostream>
#include "socket.hpp"
using namespace std;
int main ()
{
Sock info;
Recv ret;
int i = 0, val = 1024;
string s, req("Donnees a envoyer");
try
{
info=connect("172.0.0.1", 6666, Tcp);
}
catch (int tmp) // Traitement de l'exception
{
cerr << "Erreur dans la connexion" << endl;
return tmp;
}
if(send(info, req, Tcp) !=0)
{
cerr << "Erreur lors de l'envoi de la requete : " << req << endl;
disconnect(info, Tcp);
return -4;
}
ret.nb=1;
while(ret.nb>0 && i<=val)
{
ret=recv(info,Tcp);
if (ret.nb==SOCKET_ERROR)
{
cerr << "ERREUR : Aucune données recue" << endl;
disconnect(info, Tcp);
retour= -2;
}
i++;
s+=ret.c
}
cout << "Message recu :" << s << endl;
if (disconnect(info, Tcp) != 0)
{
cerr << "Erreur lors de la deconnection !";
return -3;
}
return 0;
}
Historique
- 24 avril 2006 10:26:52 :
- ;) J'ai enlever des cout que j'avais laissé pour des tests.
- 24 avril 2006 10:35:43 :
- Ajout de --> "Sous windows ne pas oublier de linker avec "libwsock32.a" "
- 25 avril 2006 11:48:02 :
- using namespace std; dans le .cpp au lieu du .hpp
- 25 avril 2006 14:30:43 :
- Remplacement du #define par un enum pour pouvoir utiliser Tcp et Udp en meme temps !
- 25 avril 2006 14:44:10 :
- Ajout du fichier "main.cpp" montrant une utilisation de la bibliothèque.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Socket TCP/UDP [ par hobbes ]
Bonjour,j ai cru comprendre qu il existe 2 types de sockets (TCP et UDP) pouvant permettre l echange de donnees entre 2 applications sur le reseau.Pou
Erreur 10049 sur socket UDP [ par Ezekiel69 ]
Salut tous le monde...Me voici depuis plusieurs jour confronté un a problème étrange.Je veux envoyer un message par l'intermédiaire d'un packet UDP su
Proxy TCP (rediriger une connexion TCP) [ par MetalDwarf ]
Je suis en train de programmer un petit prog avec une couche reseau assez importante et j aimerais y integrer un proxy capable de rediriger toute conn
Thread et socket udp [ par eurysthe ]
Bonjour !!Voila j'ai un petit problème de thread qui me pourrit la vie.J'ai crée un thread qui doit écouter en boucle les informations qui transite su
EVENEMENTS WINSOCK [ par DeAtHCrAsH ]
Quelqu'un aurait il une liste detaillé des differents evenements mis en place pour mes socket ? (WM_SOCKET)Et sans MFC ou VCL !Du genre l'evenement qu
Problème de socket UDP sous linux [ par RaygKross ]
Salut à tousMon problème est je dois créer un programme manager snmpLes port de SNMP sont 161 et 162J'initialise ma structure de type sockaddr_in avec
Winsock simple... [ par DeAtHCrAsH ]
Comment faire pour que le serveur puisse gerer plusieurs client a la fois ?Dois-je declarer autant de socket qu'il y a de client ?Ou y a t'il un equiv
pb socket [ par surfeurnet ]
voici mon programme qui a pour l'instant pour unique but de se connecter à un serveur :# include <stdio.h># include <winsock2.h># pragma c
Raw Socket -> TCP/IP [ par krum ]
Voila plus d'une semaine que je fouille/cherche sur les moteurs de recherches,les forums ..des sources,des tutos,des papers sur les raw sockets (sous
recvfrom + udp + '\n' [ par vegetaline ]
salutune appli client / serveur sous linux qui communique (enfin qui essaye) avec des sockets INTERNET en mode NON CONNECTE (en udp :)pb -> le recv
|
Derniers Blogs
TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3 par ROMELARD Fabrice
Speaker: Bernard Ourghanlian Cette session est comme chaque jour transmise en live par BrainSonic, et j'ai donc suivi cette troisième pleinière par ce moyen sur mon iPad . Elle est dédiée comme chaque année à la mise en perspective de l'é...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE !MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE ! par Vko
Hier durant une session dédiée aux Techdays 2012, j'ai eu le plaisir d'annoncer la sortie de la Béta 2 de Mishra Reader. C'est quoi ? Pour les utilisateurs, c'est une vraie expérience de lecture de flux RSS sur Windows. Rien à voir avec les produit...
Cliquez pour lire la suite de l'article par Vko [FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi WORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBEWORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBE par JeremyJeanson
Depuis déjà un an, je conseille vivement les utilisateurs de Workflow Foundation 3 à migrer vers la version 4. L'information qui va suivre ne devrait donc pas trop prendre au dépourvu les personnes qui m'ont suivi. Je profite de ce poste, pour faire le re...
Cliquez pour lire la suite de l'article par JeremyJeanson TECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PCTECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PC par ROMELARD Fabrice
Speakers: Thierry Rapatout, Antoine Petit et Xavier Trebbia Cette session entre dans le cadre des RDV Décideurs des TechDays 2012, elle est liée à la consumérisation de l'IT et la mise en place du "DeskTop as a Service" dans de plus en ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|