begin process at 2012 05 27 20:23:50
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Réseaux & Internet

 > LIBRAIRIE POUR SOCKETS C++

LIBRAIRIE POUR SOCKETS C++


 Information sur la source

Note :
Aucune note
Catégorie :Réseaux & Internet Classé sous :socket, UNIX, client serveur Niveau :Débutant Date de création :29/05/2010 Date de mise à jour :05/06/2010 22:35:48 Vu :3 651

Auteur : genetApt151

Ecrire un message privé
Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note

 Description

Voici une source permettant de créer des clients et des serveurs basées sur les sockets pour système UNIX.

Pour cela il suffit d'implémenter la méthode virtuelle interaction.
La partie connexion est gérée automatiquement. Chaque connexion d'un client est gérée par un thead.

note : ne fonctionne pas sous windows.

La source contient un exemple d'implémentation d'un client et d'un serveur.

Le serveur cle/valeur implémente les operations suivantes:
  - GET  CLE
  - PUT  CLE  VALEUR
  - DEL  CLE
  - QUIT

Les applications doivent être lancées à partir du terminal :
serveur : ./server-word-word 23000
client : ./client-word-word localhost 23000

telecharger source : http://www.megaupload.com/?d=VKWF64L6

Source

  • #ifndef _SOCKET_HH_
  • #define _SOCKET_HH_
  • #include "libsocketException.h"
  • extern "C"
  • {
  • #include <stdlib.h>
  • #include <stdio.h>
  • };
  • #include <iostream>
  • #include <sstream>
  • namespace libsocket
  • {
  • /*____________________________________________________________________________________________*/
  • /**
  • * une socket.
  • **/
  • class Socket
  • {
  • protected:
  • int _fd;// descripteur de la socket
  • virtual void socket() = 0;
  • virtual void bind(int port) = 0;
  • public:
  • Socket();
  • virtual void close()=0;
  • void setFd(int fd);
  • int getFd();
  • };
  • }
  • #endif
  • #include "libsocketTcp.h"
  • extern "C"
  • {
  • #include <sys/types.h>
  • #include <sys/socket.h>
  • #include <netdb.h>
  • #include <errno.h>
  • #include <netinet/in.h>
  • #include <string.h>
  • };
  • #include <iostream>
  • #include <sstream>
  • #include <pthread.h> // librairie thread
  • namespace libsocket
  • {
  • /*************************************************************************/
  • /** Server **/
  • /*************************************************************************/
  • /*_____________________________________________________________________________*/
  • /**
  • **/
  • void ServerTcp::run(int port)
  • {
  • socket();
  • bind(port);
  • listen(10);
  • loop();
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * boucle d'intéraction
  • **/
  • void ServerTcp::loop()
  • {
  • /*while (true)
  • {
  • SocketTcp client;
  • accept(client);
  • std::cout<<"apres:"<<client.getFd()<<std::endl;
  • if(fork() == 0)
  • {
  • printf("connexion \n");
  • interaction(client);
  • client.close();
  • printf("deconnexion \n");
  • exit(0);
  • }
  • }*/
  • while (true)
  • {
  • SocketTcp* client = new SocketTcp();
  • accept(*client);
  • pthread_t num_thread[1];
  • void * tab[2] = {this,client};
  • if (pthread_create(&num_thread[0], NULL, (void *(*)(void *))&ServerTcp::startThread,tab) == -1)
  • perror ("problème creation du thread\n");
  • }
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * on est obligé de passer par une métode static pour utiliser un thread
  • **/
  • void* ServerTcp::startThread ( void* Parameters[] )
  • {
  • ServerTcp* server = reinterpret_cast<ServerTcp*>(Parameters[0]);//recupere l'objet Server
  • SocketTcp* client = reinterpret_cast<SocketTcp*>(Parameters[1]);//recupere la socket client
  • server->runThread(client);
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * methode appelé par le thread
  • **/
  • void ServerTcp::runThread(SocketTcp* client)
  • {
  • printf("connexion\n");
  • interaction(*client);//appel de la methode virtuelle interaction
  • client->close();//fermeture de la socket
  • delete client;//liberation du pointeur client déclaré dans Server::loop
  • printf("deconnexion \n");
  • pthread_exit(NULL);//detruit le thread
  • }
  • /*************************************************************************/
  • /** Client **/
  • /*************************************************************************/
  • /*_____________________________________________________________________________*/
  • /**
  • * utilise les méthodes de Socket pour établir une connexion
  • * à une serveur lancer l'interaction
  • **/
  • void ClientTcp::run(const char* host, int port)
  • {
  • socket();
  • connect(host,port);
  • interaction();
  • close();
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * cette variante appelle la précédente
  • **/
  • void ClientTcp::run(string& host, int port)
  • {
  • run(host.c_str(),port);
  • }
  • };
  • #include "socketTcp.h"
  • #include <iostream>
  • using namespace std;
  • namespace libsocket
  • {
  • /*_____________________________________________________________________________*/
  • /**
  • * invoque l'appel système socket
  • **/
  • void SocketTcp::socket()
  • {
  • _fd = ::socket(PF_INET, SOCK_STREAM, 0); // appel la fonction socket de c.
  • if (_fd < 0) throw ErrnoExcept("socket");
  • }
  • /*_____________________________________________________________________________*/
  • void SocketTcp::connect(const char* host, int port)
  • {
  • ostringstream os;
  • os<<port;
  • socket();
  • struct addrinfo *serv_addr = 0;
  • int k = getaddrinfo(host,os.str().c_str(),0,&serv_addr);//obtebir une structure d adresse
  • if(k != 0)
  • throw ErrnoExcept("getaddrinfo");
  • while(k=::connect(_fd,serv_addr->ai_addr,serv_addr->ai_addrlen))
  • {
  • if(k<0)
  • if (errno==EAGAIN || errno==EINTR) continue;
  • else
  • throw ErrnoExcept("serveur indisponible");
  • }
  • freeaddrinfo(serv_addr);
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * ferme la socket
  • **/
  • void SocketTcp::close()
  • {
  • while (_fd >= 0)
  • {
  • int r = ::close(_fd);
  • if (r < 0)
  • {
  • if (errno == EINTR) continue;
  • else throw ErrnoExcept("close");
  • }
  • break;
  • }
  • _fd = -1;
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * lie la socket au port sur toutes les interfaces.
  • **/
  • void SocketTcp::bind(int port)
  • {
  • struct sockaddr_in addr;
  • addr.sin_family = AF_INET;
  • addr.sin_port = htons(port);
  • addr.sin_addr.s_addr = htonl(INADDR_ANY);
  • if (::bind(_fd, (struct sockaddr *) &addr, sizeof(addr))==-1)
  • throw ErrnoExcept("bind");
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * \c listen pour indiquer qu'on va écouter sur cette socket.
  • **/
  • void SocketTcp::listen(int backlog)
  • {
  • if (::listen(_fd, backlog)==-1)
  • throw ErrnoExcept("listen");
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * Pour attendre et accepter une demande de connexion d'un client. C
  • **/
  • void SocketTcp::accept(Socket& client)
  • {
  • while (true)
  • {
  • int cli = ::accept(_fd, NULL, NULL);
  • if (cli < 0)
  • {
  • //cas exceptionnels de fonctionnement normal
  • if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) continue;
  • else throw ErrnoExcept("accept");
  • }
  • client.setFd(cli);
  • break;
  • }
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * écrit sur la socket exactement n octets pointés par buf.
  • **/
  • void SocketTcp::write(const char* buf, int n)
  • {
  • while (n > 0)
  • {
  • int k = ::write(_fd, buf, n);
  • if (k < 0)
  • {
  • if (errno == EAGAIN || errno == EINTR) continue;
  • else throw ErrnoExcept("write");
  • }
  • buf += k;
  • n -= k;
  • }
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * ecrit sur la socket en calculant elle-même la
  • * longueur de la chaîne de caractères.
  • **/
  • void SocketTcp::write(const char* buf)
  • {
  • write(buf, strlen(buf)+1);//+1 pour compter le '\0'
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • /**
  • * Pour attendre et accepter une demande de connexion d'un client.
  • **/
  • void SocketTcp::write(const string& buf)
  • {
  • write(buf.c_str(), buf.length()+1);//+1 pour compter le '\0'
  • }
  • /*_____________________________________________________________________________*/
  • void SocketTcp::read(char *buf,int n)
  • {
  • while (n > 0)
  • {
  • int k = ::read(_fd, buf, n);
  • if (k < 0)
  • if (errno == EAGAIN || errno == EINTR) continue;
  • else throw ErrnoExcept("read");
  • buf += k;
  • n -= k;
  • }
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * lit sur la socket exactement n octets et les retourne sous
  • la forme d'un string. (ne pas compter le caractère de fin de chaine '\0')
  • **/
  • string SocketTcp::read(int n)
  • {
  • char mes[n+1]; //a corriger !!
  • read(mes,n);
  • int taille = strlen(mes);
  • if(mes[taille] != '\0')
  • mes[taille+1] = '\0';
  • return (string) mes;
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * lire un entier
  • **/
  • int32_t SocketTcp::readInt32()
  • {
  • int32_t v;
  • read((char *) &v,sizeof(v));
  • return ntohl(v);
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * ecrire un entier
  • **/
  • void SocketTcp::writeInt32(int i)
  • {
  • int32_t v = htonl(i);
  • write (( const char *) &v,sizeof(v));
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * lit une ligne de texte et retourne un string (sans le \n)
  • **/
  • string SocketTcp::readLine()
  • {
  • char c;
  • ostringstream os;
  • while(true)
  • {
  • int k = ::read(_fd,&c,1);
  • if (k <= 0)//si k==0 on leve une exception pour eviter une boucle infinie
  • if (errno == EAGAIN || errno == EINTR) continue;
  • else throw ErrnoExcept("readline");
  • if(c == EOF || c == '\0' || c == '\n') break;
  • else os << c;
  • }
  • return os.str();
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * lit un mot délimité par un espaces.
  • **/
  • string SocketTcp::readWord()
  • {
  • char c;
  • ostringstream res ;
  • int k;
  • //supprime les espaces
  • while(true)
  • {
  • k = ::read(_fd,&c,1);
  • if (k <= 0) //si k==0 on leve une exception pour eviter une boucle infinie
  • if (errno == EAGAIN || errno == EINTR) continue;
  • else throw ErrnoExcept("readword");
  • if(c == EOF || c == '\n' || c == '\0') return "";
  • if(!isspace(c))
  • {
  • res<<c;
  • break;
  • }
  • }
  • //lecture d'un mot
  • while(true)
  • {
  • k= ::read(_fd,&c,1);
  • if (k <= 0)
  • if (errno == EAGAIN || errno == EINTR) continue;
  • else throw ErrnoExcept("readword");
  • if(c == EOF || c == '\0' || c == '\n' || isspace(c)) break;
  • else
  • res << c;
  • }
  • return res.str();
  • }
  • }
  • #include "socketUdp.h"
  • #include <iostream>
  • using namespace std;
  • namespace libsocket
  • {
  • /*_____________________________________________________________________________*/
  • /**
  • * invoque l'appel système socket
  • **/
  • void SocketUdp::socket()
  • {
  • _fd = ::socket(AF_INET, SOCK_DGRAM, 0); // appel la fonction socket de c.
  • if (_fd < 0) throw ErrnoExcept("socket");
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * ferme la socket
  • **/
  • void SocketUdp::close()
  • {
  • while (_fd >= 0)
  • {
  • int r = ::close(_fd);
  • if (r < 0)
  • {
  • if (errno == EINTR) continue;
  • else throw ErrnoExcept("close");
  • }
  • break;
  • }
  • _fd = -1;
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * lie la socket au port sur toutes les interfaces.
  • **/
  • void SocketUdp::bind(int port)
  • {
  • this->addr.sin_family = AF_INET;
  • this->addr.sin_port = htons(port);
  • this->addr.sin_addr.s_addr = htonl(INADDR_ANY);
  • if (::bind(this->_fd, (struct sockaddr *) &this->addr, sizeof(this->addr))!=0)
  • throw ErrnoExcept("bind");
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * envoyer un message.
  • **/
  • void SocketUdp::sendto(const char* mes)
  • {
  • ::sendto(this->getFd(),mes,strlen(mes)+1,0,(struct sockaddr*)&this->addr,sizeof(addr));
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * envoyer un message.
  • **/
  • void SocketUdp::sendto(string mes)
  • {
  • sendto(mes.c_str());
  • }
  • /*_____________________________________________________________________________*/
  • /**
  • * recevoir un message.
  • **/
  • string SocketUdp::recvfrom(int n)
  • {
  • char mes[n+1];
  • int flag = ::recvfrom(this->getFd(),mes,n,0,(struct sockaddr*)&this->addr,&this->lg_app);
  • int taille = strlen(mes);
  • if(mes[taille] != '\0')
  • mes[taille+1] = '\0';
  • return (string) mes;
  • }
  • }
#ifndef _SOCKET_HH_
#define _SOCKET_HH_

#include "libsocketException.h"

extern "C"
{
	#include <stdlib.h>
	#include <stdio.h>
};

#include <iostream>
#include <sstream>

namespace libsocket
{
 /*____________________________________________________________________________________________*/
  /** 
  * une socket.
  **/
  class Socket
  {
	protected:
		int _fd;// descripteur de la socket
		virtual void socket() = 0;		
		virtual void bind(int port) = 0;

	public:
		Socket();
		virtual void close()=0;
		void setFd(int fd);
		int getFd();
  };	
}

#endif

#include "libsocketTcp.h"

extern "C"
{
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netdb.h>
	#include <errno.h>
	#include <netinet/in.h>
	#include <string.h>
};

#include <iostream>
#include <sstream>
#include <pthread.h>  // librairie thread

namespace libsocket
{
 /*************************************************************************/
 /**  							Server									 **/
 /*************************************************************************/
  /*_____________________________________________________________________________*/
  /**

  **/
  void ServerTcp::run(int port)
  {
    socket();
    bind(port);
    listen(10);
    loop();
  }
  
  /*_____________________________________________________________________________*/
  /**
  * boucle d'intéraction
  **/
  void ServerTcp::loop()
  {
	/*while (true)
    {
		SocketTcp client;
		accept(client);
		std::cout<<"apres:"<<client.getFd()<<std::endl;

		if(fork() == 0)
		{
			printf("connexion \n");
			interaction(client);
      		client.close();
			printf("deconnexion \n");
			exit(0);
		}
    }*/
    
    while (true)
    {
		SocketTcp* client = new SocketTcp();
		accept(*client);
		
		pthread_t num_thread[1]; 
		
		void * tab[2] = {this,client};
			
		if (pthread_create(&num_thread[0], NULL, (void *(*)(void *))&ServerTcp::startThread,tab) == -1)
			perror ("problème creation du thread\n");
    }
  }
  
/*_____________________________________________________________________________*/
/**
 * on est obligé de passer par une métode static pour utiliser un thread 
 **/
 void* ServerTcp::startThread ( void* Parameters[] ) 
 {
	ServerTcp* server = reinterpret_cast<ServerTcp*>(Parameters[0]);//recupere l'objet Server
	SocketTcp* client = reinterpret_cast<SocketTcp*>(Parameters[1]);//recupere la socket client
	server->runThread(client);
 }
 
/*_____________________________________________________________________________*/
/**
 * methode appelé par le thread 
 **/
 void ServerTcp::runThread(SocketTcp* client)
 {
	printf("connexion\n");
	
	interaction(*client);//appel de la methode virtuelle interaction 
    client->close();//fermeture de la socket
    delete client;//liberation du pointeur client déclaré dans Server::loop
    
    printf("deconnexion \n");
	pthread_exit(NULL);//detruit le thread 
 }
 
  /*************************************************************************/
 /**  							Client									 **/
 /*************************************************************************/

  /*_____________________________________________________________________________*/
  /**
  *  utilise les méthodes de Socket pour établir une connexion
  *        à une serveur lancer l'interaction
  **/
  void ClientTcp::run(const char* host, int port)
  {
    socket();
    connect(host,port);
    interaction();
    close();
  }

  /*_____________________________________________________________________________*/
  /** 
  * cette variante appelle la précédente
  **/
  void ClientTcp::run(string& host, int port)
  {
    run(host.c_str(),port);
  }
   
};

#include "socketTcp.h"
#include <iostream>
using namespace std;

namespace libsocket
{   
  /*_____________________________________________________________________________*/
  /**
  * invoque l'appel système socket 
  **/
  void SocketTcp::socket()
  {
    _fd = ::socket(PF_INET, SOCK_STREAM, 0);  // appel la fonction socket de c.
    if (_fd < 0) throw ErrnoExcept("socket");
  }
  
  /*_____________________________________________________________________________*/
  void SocketTcp::connect(const char* host, int port)
  {
	ostringstream os;
	os<<port;

    socket();
    struct addrinfo *serv_addr = 0;
    int k = getaddrinfo(host,os.str().c_str(),0,&serv_addr);//obtebir une structure d adresse
    if(k != 0)
		throw ErrnoExcept("getaddrinfo");

    while(k=::connect(_fd,serv_addr->ai_addr,serv_addr->ai_addrlen))
    {
		if(k<0)   
			if (errno==EAGAIN || errno==EINTR) continue;
			else
				throw ErrnoExcept("serveur indisponible");
    }
    
    freeaddrinfo(serv_addr);
  }
  

  
  /*_____________________________________________________________________________*/
  /**
  *  ferme la socket 
  **/
  void SocketTcp::close()
  {
    while (_fd >= 0)
    {
		int r = ::close(_fd);
		if (r < 0)
		{
			if (errno == EINTR) continue;
			else throw ErrnoExcept("close");
		}
		break;
    }
    _fd = -1;
  }
  
  /*_____________________________________________________________________________*/
  /** 
  * lie la socket au port sur toutes les interfaces.
  **/
  void SocketTcp::bind(int port)
  {
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (::bind(_fd, (struct sockaddr *) &addr, sizeof(addr))==-1)
      throw ErrnoExcept("bind");
  }

  /*_____________________________________________________________________________*/
  /**
  * \c listen pour indiquer qu'on va écouter sur cette socket.
  **/
  void SocketTcp::listen(int backlog)
  {
    if (::listen(_fd, backlog)==-1)
      throw ErrnoExcept("listen");
  }

  /*_____________________________________________________________________________*/
  /**
  *  Pour attendre et accepter une demande de connexion d'un client.  C
  **/
  void SocketTcp::accept(Socket& client)
  {
    while (true)
    {
		int cli = ::accept(_fd, NULL, NULL);
		if (cli < 0)
		{
			//cas exceptionnels de fonctionnement normal
			if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) continue;
			else throw ErrnoExcept("accept");
		}

		client.setFd(cli);
		break;
    }
  }
  
   /*_____________________________________________________________________________*/
  /**
  * écrit sur la socket exactement n octets pointés par buf.
  **/
  void SocketTcp::write(const char* buf, int n)
  {
    while (n > 0)
    {
		int k = ::write(_fd, buf, n);
		if (k < 0)
		{
			if (errno == EAGAIN || errno == EINTR) continue;
			else throw ErrnoExcept("write");
		}
		buf += k;
		n -= k;
    }
  }

  /*_____________________________________________________________________________*/
  /**
  * ecrit sur la socket en calculant elle-même la
  * longueur de la chaîne de caractères.
  **/
  void SocketTcp::write(const char* buf)
  {
    write(buf, strlen(buf)+1);//+1 pour compter le '\0'
  }

  /*_____________________________________________________________________________*/
  /**
  /**
  *  Pour attendre et accepter une demande de connexion d'un client.  
  **/
  void SocketTcp::write(const string& buf)
  {
    write(buf.c_str(), buf.length()+1);//+1 pour compter le '\0'
  }
  
  /*_____________________________________________________________________________*/
  void SocketTcp::read(char *buf,int n)
  {
	while (n > 0)
    {
		int k = ::read(_fd, buf, n);
		if (k < 0)
			if (errno == EAGAIN || errno == EINTR) continue;
			else throw ErrnoExcept("read");
			
		buf += k;
		n -= k;
    }
  }

  /*_____________________________________________________________________________*/
  /**
  *  lit sur la socket exactement n octets et les retourne sous
          la forme d'un string. (ne pas compter le caractère de fin de chaine '\0')
  **/ 
  string SocketTcp::read(int n)
  {
    char mes[n+1]; //a corriger !!
    read(mes,n);
    
    int taille = strlen(mes);
    
    if(mes[taille] != '\0')
		mes[taille+1] = '\0';
    
    return (string) mes;
  }

  /*_____________________________________________________________________________*/
  /**
  * lire un entier
  **/
  int32_t SocketTcp::readInt32()
  {
    int32_t v;  
    read((char *) &v,sizeof(v));
    
    return ntohl(v);
  }

  /*_____________________________________________________________________________*/
  /**
  *  ecrire un entier
  **/
  void SocketTcp::writeInt32(int i)
  {
     int32_t v = htonl(i);   
     write (( const char *) &v,sizeof(v));
  }
   
  /*_____________________________________________________________________________*/
  /**
  *  lit une ligne de texte et retourne un string (sans le \n)
  **/
  string SocketTcp::readLine()
  {
    char  c;
	ostringstream os;
	
    while(true)
    {
		int k = ::read(_fd,&c,1);
		if (k <= 0)//si k==0 on leve une exception pour eviter une boucle infinie
			if (errno == EAGAIN || errno == EINTR) continue;
			else throw ErrnoExcept("readline");

		if(c == EOF || c == '\0' || c == '\n') break;
		else os << c;
	}

    return os.str();		  
  }

  /*_____________________________________________________________________________*/
  /**
  *  lit un mot délimité par un espaces.
  **/ 
  string SocketTcp::readWord()
  { 
      char c;
	  ostringstream res ;
	  int k;

	  //supprime les espaces
	  while(true)
	  {
		k = ::read(_fd,&c,1);
		if (k <= 0) //si k==0 on leve une exception pour eviter une boucle infinie
			if (errno == EAGAIN || errno == EINTR) continue;
			else throw ErrnoExcept("readword");

		if(c == EOF || c == '\n' || c == '\0') return "";
		if(!isspace(c))
		{
			res<<c;
			break;
		}
	  }

	  //lecture d'un mot
	  while(true)
	  {
		k= ::read(_fd,&c,1);
		if (k <= 0)
			if (errno == EAGAIN || errno == EINTR) continue;
			else throw ErrnoExcept("readword");
		
		if(c == EOF || c == '\0' || c == '\n' || isspace(c)) break; 
		else
			res << c;
	  }
		
  	  return res.str();	
  }
	
}

#include "socketUdp.h"
#include <iostream>
using namespace std;

namespace libsocket
{
	
  /*_____________________________________________________________________________*/
  /**
  * invoque l'appel système socket 
  **/
  void SocketUdp::socket()
  {
    _fd = ::socket(AF_INET, SOCK_DGRAM, 0);  // appel la fonction socket de c.
    if (_fd < 0) throw ErrnoExcept("socket");
  }
    
  /*_____________________________________________________________________________*/
  /**
  *  ferme la socket 
  **/
  void SocketUdp::close()
  {
    while (_fd >= 0)
    {
		int r = ::close(_fd);
		if (r < 0)
		{
			if (errno == EINTR) continue;
			else throw ErrnoExcept("close");
		}
		break;
    }
    _fd = -1;
  }
  
  /*_____________________________________________________________________________*/
  /** 
  * lie la socket au port sur toutes les interfaces.
  **/
  void SocketUdp::bind(int port)
  {
    this->addr.sin_family = AF_INET;
    this->addr.sin_port = htons(port);
    this->addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (::bind(this->_fd, (struct sockaddr *) &this->addr, sizeof(this->addr))!=0)
      throw ErrnoExcept("bind");
  }
  
   /*_____________________________________________________________________________*/
  /** 
  * envoyer un message.
  **/ 		
  void SocketUdp::sendto(const char* mes)
  {
	::sendto(this->getFd(),mes,strlen(mes)+1,0,(struct sockaddr*)&this->addr,sizeof(addr));
  }
	
  /*_____________________________________________________________________________*/
  /** 
  * envoyer un message.
  **/	
  void SocketUdp::sendto(string mes)
  {
	sendto(mes.c_str());
  }
	
  /*_____________________________________________________________________________*/
  /** 
  * recevoir un message.
  **/	
  string SocketUdp::recvfrom(int n)
  {
	 char mes[n+1];
						
	 int flag = ::recvfrom(this->getFd(),mes,n,0,(struct sockaddr*)&this->addr,&this->lg_app);
			
	 int taille = strlen(mes);
	 if(mes[taille] != '\0')
		mes[taille+1] = '\0';
    
	return (string) mes;
  }
	
}



 Historique

29 mai 2010 20:33:47 :
ajout lien zip
05 juin 2010 22:35:48 :
ajout socket udp

 Sources de la même categorie

Source avec Zip Source avec une capture MINI SERVEUR HTTP [WINDOWS] par ganjarasta
Source avec Zip Source avec une capture CLIENT DE TEST MODBUS TCP par brunovan
Source avec Zip Source avec une capture SCANIP [ARP / ICMP] par ganjarasta
Source avec Zip Source avec une capture TRACEROUTE [WINPCAP] par ganjarasta
Source avec Zip SERVEUR MULTITHREAD [LINUX/WIN] par nipepsinicolas

 Sources en rapport avec celle ci

Source avec Zip SERVEUR MULTITHREAD [LINUX/WIN] par nipepsinicolas
Source avec Zip Source avec une capture SECURE REMOTE SHELL [WIN32] par ganjarasta
Source avec Zip MINICHAT MULTI-CLIENT par wisar
SOCKET CPP par baptchr55
SIMPLE SCANNER DE PORTS par Vb6Malade

Commentaires et avis

Commentaire de LeFauve42 le 31/05/2010 11:27:09

Bonjour,

Ca a l'air pas mal, mais je ne vois aucun mecanisme de bufferisation.
Envoyer des bytes ou des shorts un par un peu vraiment ralentir le trafic.
Il vaut mieux preparer un buffer de quelques Ko et faire un flush quand on veut tout envoyer (j'ai reussi a diviser mes temps de transmission par 10 grace a ce genre d'ameliorations).

C'est surtout efficace si l'un des deux hosts est tres vieux (dans mon cas, c'etait une communication avec un robot tournant sous Win98SE) mais ca doit quand meme aider avec des machines plus recentes.

Dans le meme genre, tes fonctions put_uintxx et get_uintxx sont tres inefficaces (faire 4 appels systemes pour ecrire 32 bits c'est (au moins) 3 de trop. Et je ne parle meme pas de tes fonctions pour lire une ligne ou un mot, qui lisent la socket caractere par caractere...

Pour faire simple, ton code est tres beau, mais du coup tres ineficace.
L'interet d'utiliser une lib avec des classes de haut niveau est aussi de pouvoir planquer dedans des trucs moins beaux mais efficaces (surtout pour des trucs de bas niveau comme les sockets).
Les gens qui utilisent la lib (si elle marche bien) ne regardent jamais dedans, alors autant faire un truc le plus efficace possible (tant que l'interface est jolie et pratique a utiliser).

Eric

NB: Si tu fais des tests de performance pour verifier ce que je te dis, utilise bien 2 machines, car sur le meme pc, les optimisations du loopback device (127.0.0.1) vont certainement masquer les defauts.

NB2: Si tu veux t'amuser a piloter un robot pour tester ta lib de sockets, on cherche des volontaires :o)

Commentaire de Ks4ssPeuk le 31/05/2010 13:05:57

Je ne sais pas si tu es de l'IUT d'Orleans, mais il me semble que ce code source est calqué à 100% sur le code de Mr Duchier. Si c'est le cas c'est pas beau de faire ça ...

Commentaire de sboli le 31/05/2010 13:27:03

Ca peut paraitre bizarre comme remarque, mais ton niveau d'abstraction n'est pas assez élevé.
Dans une classe comme celle-ci, close(), bind(), listen(), accept() ne devrait pas être accessibles. A la limite j'aurais fait ça avec deux fonctions: read(unsigned), write(const Buffer&).

Au lieu de te prendre la tête avec les int8/16/32 tu peut envoyer n'importe que quoi (qui a son op<< sur ostream) en sérialisant via std::ostringstream.

Commentaire de YahyaHajji le 01/06/2010 20:34:03


Le lien pour le Zip le voilà

http://www.cppfrance.com/telecharger.aspx/?ID=51824

Commentaire de rpoline le 01/06/2010 20:34:39

Le code est effectivement assez jolie mais pas en adéquation avec une utilisation intensive.

Typiquement dans ce genre d'application il vaut mieux écrire une fonction qui ré-assemble les données en provenance de la socket (si fragmentation) puis décoder la trame complète en provenance du Réseau avec une méthode dédiée.

J'ai pour ma part développer il y à quelques années développer une Solution Client/Serveur capable de gérer 600 connexions simultanées il nous a fallu 6 mois pour mettre au point le système.....


Richard

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Socket [ par edpunisher ] kikoo, j ai un projet o&#251; je doit utiliser les socket entre une machine windows et une autre unix sauf que j ai tt asseyer mais rien ne marche, le Socket entre machine windows et unix [ par edpunisher ] kikoo, j ai un projet o&#251; je doit utiliser les socket entre une machine windows et une autre unix sauf que j ai tt asseyer mais rien ne marche, le client ftp soux unix [ par eilyn ] salutvoila je voudrais faire un client ftp sous unixdonc pour créer ma socket j'utilise la méthodeSOCKET s;s = socket (AF_INET,SOCK_STREAM,"protocol") socket AF_UNIX [ par hobbes ] Bonjour,Je cherche les sources de l'utilisation des sockets avec AF_UNIX.QQ peut il m aider???Bonne programmation. socket unix locale [ par gaussdelphine ] je souhaite faire un envoi de socket unix de domaine AF_UNIX avec la même adresse pour le client et le serveur.Est ce que c'est possible??J'obtiens un IP_HDRINCL socket Raw [ par gaussdelphine ] Je voudrais utiliser la primitive: setsockopt pour fixer l'optionIP_HDRINCL à 1. Le problème c'est que j'utilise cygwin qui d'après ce que j'ai lu sur 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 socket [ par gaussdelphine ] J'essaye de programmer une socket em mode datagramme SOCK_RAW. J'ai le message d'erreur suivant à la compilation:sizeof applied to an incomplete type Connexion/Deconnexion/Reconnexion Socket [ par tequila1 ] BonjourJ'ai développé une DLL, qui se connecte à un serveur de données via socket.J'utilise pour cela les MFC. Je me connecte au serveur, je recois le socket + IE6 - aide svp [ par jrecan ] bonjour, je voudrais créer un proxy sous winXPpour cela, je dois récupérer l'adresse url que je tape dans IE6.Dans un premier temps, j aimerais faire


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,702 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales