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
UNE JOLIE-HORLOGE ET PAS QU'UN PEU !UNE JOLIE-HORLOGE ET PAS QU'UN PEU ! par neodante
Pour les possesseurs d'iPhone, ça y est Bijin Tokei - qui se traduit littéralement en Français par " Jolie Horloge " - est arrivé et GRATUITEMENT s'il vous plaît ! Après la version Tokyo, Hokkaido, night club, racing, Gal, "pour les mademoiselles'", . voi...
Cliquez pour lire la suite de l'article par neodante TECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICESTECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICES par ROMELARD Fabrice
Animé par: Gaetan Bouveret et Julien Chomarat Business Connectivity Services (BCS) est dans SharePoint 2010 la version 2 de Business Data Catalog (BDC dans SharePoint 2007). Il s'agit de la solution permettant de visualiser des données provenan...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE[DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE par orion
Comme de nombreux geek, je suis un grand amateur de série TV et je rate régulièrement des épisodes de mes séries préférés. Une solution s'offre à vous avec ce merveilleux site : Tv Gorge - www.tvgorge.com Moteur de recherche à l'appui, vous pouvez ...
Cliquez pour lire la suite de l'article par orion TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Vincent Bellet et Baptiste Giraudier La BI dans SharePoint 2010, Les nouveaux services d'application dans SP2010 et SQL Server Reporting services 2008 R2. La BI dans SharePoint est généralisée pour tous afin de permettre à tous les coll...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Forum
RE : WIN APIRE : WIN API par racpp
Cliquez pour lire la suite par racpp WIN APIWIN API par omarino_007
Cliquez pour lire la suite par omarino_007
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|