From 79936bfa0c3452f532564d12a1bcbbabc12360bc Mon Sep 17 00:00:00 2001 From: glenux Date: Tue, 10 Jan 2006 10:42:33 +0000 Subject: [PATCH] --- AUTHORS | 0 COPYING | 0 ChangeLog | 0 Doxyfile | 0 INSTALL | 0 Makefile.am | 3 + NEWS | 0 README | 0 autogen.sh | 11 + config.h.in | 61 +++ configure.in | 35 ++ src/Makefile.am | 28 ++ src/XSock.cpp | 276 ++++++++++++++ src/XSock.h | 110 ++++++ src/XSockTCP.cpp | 102 +++++ src/XSockUDP.cpp | 83 +++++ src/XSockUDP_RELIABLE.cpp | 531 +++++++++++++++++++++++++++ src/XSock_errors.h | 33 ++ src/XSock_global.h | 35 ++ src/XSock_iface.h | 10 + src/test/Makefile.am | 2 + src/test/client_Echo_udp/Makefile.am | 18 + src/test/server_Echo_udp/Makefile.am | 18 + 23 files changed, 1356 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Doxyfile create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100755 autogen.sh create mode 100644 config.h.in create mode 100644 configure.in create mode 100644 src/Makefile.am create mode 100644 src/XSock.cpp create mode 100644 src/XSock.h create mode 100644 src/XSockTCP.cpp create mode 100644 src/XSockUDP.cpp create mode 100644 src/XSockUDP_RELIABLE.cpp create mode 100644 src/XSock_errors.h create mode 100644 src/XSock_global.h create mode 100644 src/XSock_iface.h create mode 100644 src/test/Makefile.am create mode 100644 src/test/client_Echo_udp/Makefile.am create mode 100644 src/test/server_Echo_udp/Makefile.am diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..e69de29 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..e1e3ed3 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +EXTRA_DIST = doc INSTALL README Doxyfile autogen.sh diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..b6037f1 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,11 @@ +echo "libtoolize..." +libtoolize +echo "aclocal..." +aclocal +echo "autoheader..." +autoheader +echo "autoconf..." +autoconf +echo "automake..." +automake -a +echo "ok." diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..453e651 --- /dev/null +++ b/config.h.in @@ -0,0 +1,61 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOSTREAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SSTREAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..a3cf379 --- /dev/null +++ b/configure.in @@ -0,0 +1,35 @@ + +AC_INIT([xsock], [0.5], [shamox@free.fr,glenux@gmail.com]) +AC_PREREQ(2.50) + +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +AM_INIT_AUTOMAKE([xsock],[0.5]) + +AM_CONFIG_HEADER(config.h) +AC_CONFIG_SRCDIR([src/XSock.h]) +AC_PROG_INSTALL + +AC_ISC_POSIX +AC_PROG_CC + +AC_PROG_CXX +AC_PROG_CPP +AC_PROG_CXXCPP +AC_PROG_INSTALL + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +AC_HEADER_STDC([stdio.h stdlib.h string.h unistd.h math.h time.h fcntl.h sys/stat.h sys/socket.h sys/errno.h sys/time.h sys/types.h netinet/in.h netdb.h arpa/inet.h]) + +AC_CHECK_HEADERS([iostream sstream],,AC_MSG_ERROR([You need to have the libstdc++ headers installed])) + + +AM_PROG_LIBTOOL + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT + + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..f589e47 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,28 @@ +SUBDIRS = . + +lib_LTLIBRARIES = libXSock.la + +#bin_PROGRAMS = libulm.o + +libXSock_la_SOURCES = \ + XSock.cpp \ + XSockTCP.cpp \ + XSockUDP.cpp \ + XSockUDP_RELIABLE.cpp + +libXSock_la_SOURCES += \ + xsock.h \ + introspect.h \ + command.h \ + macrocommand.h \ + singleton.h \ + identifiable.h + +libXSock_la_CFLAGS = -DTRACE -static + +libXSock_la_LDFLAGS = \ + -version-info 0:1:0 -no-undefined + +INCLUDES= \ + -I../ + diff --git a/src/XSock.cpp b/src/XSock.cpp new file mode 100644 index 0000000..4b4c704 --- /dev/null +++ b/src/XSock.cpp @@ -0,0 +1,276 @@ + +/*! + * \ file XSock.cpp bal bla + * + */ + +#include "XSock.h" + +/*! + * \def VERBOSE Active ou pas le mode verbeux + */ +#define VERBOSE 0 + +// constantes utilisées dans XSock.cpp et dans XSockUDP.cpp +#define NBPORTSPUB 64512 +#define PNUMPORTPUB 1025 +#define GETPORTPUB() PNUMPORTPUB+(rand()%NBPORTSPUB) + +using namespace std; +using namespace XSockExcept; + +namespace XSock { + + XSock::XSock (xsock_role role,protocol proto){ + /* initialise la structure d'addresse */ + /* on commence par vider la structure pour éviter les déchets... */ + memset(&this->_server, 0, sizeof(this->_server)); + memset(&this->_client, 0, sizeof(this->_client)); + this->_client.sin_family=AF_INET; + this->_server.sin_family=AF_INET; + + /* on initialise le systèmes de nombres aléatoires */ + srand(time(NULL)); + /* on initialise avec des addresses locales au cas où... */ + this->_client.sin_addr.s_addr=htonl(INADDR_LOOPBACK); + this->_server.sin_addr.s_addr=htonl(INADDR_LOOPBACK); + + /* et les ports au hasard */ + this->_client.sin_port=htons(0); + this->_server.sin_port=htons(0); + + /* calcule la taille de la table des descripteurs */ + this->_sockSetDSize = getdtablesize(); + + this->_role=role; + this->_proto=proto; + + this->_client_length = sizeof(this->_client); + this->_server_length = sizeof(this->_server); + + + } + + /*! + * Indique le port à utiliser sur le serveur. + */ + void XSock::port(u_short port){ + switch(this->_role){ + case CLIENT: + this->_server.sin_port=htons(port); + break; + case SERVER: + this->_server.sin_port=htons(port); + break; + default: + throw eUnknownXSockRole(); + break; + } + } + + + /*! + * Fixe la taille de la queue d'attente de connexion + */ + + void XSock::backlog(int size){ + this->_backlog=size; + } + + + /*! + * Indique l'addresse IP du serveur. + */ + + void XSock::ip(int ip){ + switch (this->_role){ + case CLIENT: + this->_server.sin_addr.s_addr=htonl(ip); + break; + case SERVER: + this->_server.sin_addr.s_addr=htonl(ip); + break; + default: + throw eUnknownXSockRole(); + break; + } + } + + void XSock::dns(string dns){ + struct hostent *he; + if ((he = gethostbyname(dns.c_str())) == NULL) { + throw eUnableToResolveName(); + } + + memcpy(&(this->_server.sin_addr.s_addr), he->h_addr_list[0], he->h_length); + + switch (this->_role){ + case CLIENT: + break; + case SERVER: + break; + default: + throw eUnknownXSockRole(); + break; + } + + } + /*! + * Connecte XSock au réseau. + */ + + void XSock::dump_info(){ + if (VERBOSE>=1){ + printf("XSock server : %d\n",this->_server.sin_addr.s_addr); + printf("XSock client : %d\n",this->_client.sin_addr.s_addr); + printf("XSock server port : %d\n",this->_server.sin_port); + printf("XSock client port : %d\n",this->_client.sin_port); + } + } + + char * XSock::getClientAddress(){ + return inet_ntoa(this->_client.sin_addr); + } + + char * XSock::getServerAddress(){ + return inet_ntoa(this->_server.sin_addr); + } + + + void XSock::launch(){ + this->dump_info(); + switch (this->_role){ + case CLIENT: + switch (this->_proto){ + case TCP: + this->launch_tcp_client(); + break; + case UDP: + this->launch_udp_client(); + break; + case UDP_RELIABLE: + this->launch_udp_reliable_client(); + break; + default: + throw eUnknownProtocol(); + break; + } + break; + case SERVER: + switch (this->_proto){ + case TCP: + this->launch_tcp_server(); + break; + case UDP: + this->launch_udp_server(); + break; + case UDP_RELIABLE: + this->launch_udp_reliable_server(); + break; + default: + throw eUnknownProtocol(); + break; + } + break; + default: + throw eUnknownXSockRole(); + break; + } + } + + /*! + * Demande a XSock de recevoir des informations. + * \param bufferData buffer de données. + * \param size taille du buffer. + */ + + ssize_t XSock::recv(void *bufferData, ssize_t size){ + switch(this->_proto){ + case TCP: + return this->recv_tcp(bufferData, size); + break; + case UDP: + return this->recv_udp(bufferData, size); + break; + case UDP_RELIABLE: + return this->recv_udp_reliable(bufferData, size); + break; + default: + throw eUnknownProtocol(); + break; + } + } + + ssize_t XSock::send(const void *bufferData, ssize_t size){ + switch(this->_proto){ + case TCP: + return this->send_tcp(bufferData, size); + break; + case UDP: + return this->send_udp(bufferData, size); + break; + case UDP_RELIABLE: + return this->send_udp_reliable(bufferData, size); + break; + default: + throw eUnknownProtocol(); + break; + } + } + + + XSock XSock::accept(){ + XSock result(CLIENT,this->_proto); + switch (this->_role){ + case CLIENT: + // TODO: râler, car le client ne recoit pas de + // connexions... + break; + case SERVER: + switch (this->_proto){ + case TCP: + result=this->accept_tcp(); + break; + case UDP: + result=this->accept_udp(); + break; + case UDP_RELIABLE: + result=this->accept_udp_reliable(); + break; + default: + throw eUnknownProtocol(); + break; + } + break; + default: + throw eUnknownXSockRole(); + break; + } + return result; + } + + void XSock::close(){ + switch (this->_proto){ + case TCP: + this->close_tcp(); + break; + case UDP: + this->close_udp(); + break; + case UDP_RELIABLE: + this->close_udp_reliable(); + break; + default: + throw eUnknownProtocol(); + break; + + } + //TODO: a faire... + } +} // end namespace + + + + + + diff --git a/src/XSock.h b/src/XSock.h new file mode 100644 index 0000000..bc88633 --- /dev/null +++ b/src/XSock.h @@ -0,0 +1,110 @@ +/*! + * \file XSock.hpp blabla + * + */ + +#ifndef _XIONFS_XSOCK +#define _XIONFS_XSOCK 1 + +#include "XSock_errors.h" +#include "XSock_global.h" +#include "XSock_iface.h" + +using namespace std; +using namespace XSockExcept; + +namespace XSock { + /* + * XSock permet de gérer une connexion TCP ou UDP. + */ + + class XSock { + private: + protocol _proto; + xsock_role _role; + + /* descripteur de la socket principale */ + int _sockFd; + + /* taille de la table des descripteurs */ + int _sockSetDSize; + + /* ensemble de sockets ouverts */ + fd_set _openSockFdSet; + + /* ensemble de sockets ouverts qui attendent d'être lus */ + fd_set _openSockFdSet_R; + + /* fixer la taille de la queue d'attente de connexions*/ + int _backlog; + + + /* membres à ajouter pour les service par dessus udp */ + // numéros de séquence entrante + u_int _secnumrecv; + // numéros de séquence sortante + u_int _secnumsend; + + /* structure d'addresse du client */ + struct sockaddr_in _client; + socklen_t _client_length; + + /* structure d'addresse du serveur */ + struct sockaddr_in _server; + socklen_t _server_length; + + void launch_tcp_client(); + void launch_udp_client(); + void launch_udp_reliable_client(); + void launch_tcp_server(); + void launch_udp_server(); + void launch_udp_reliable_server(); + + XSock accept_udp(); + XSock accept_udp_reliable(); + XSock accept_tcp(); + int sockFdTab_newPlace(); + int sockFdTab_getPlace(int); + + unsigned short XSock::getAvailablePortPub(); + + void backlog(int ); + + ssize_t send_udp(const void *, ssize_t ); + ssize_t send_udp_reliable(const void *, ssize_t ); + ssize_t send_tcp(const void *, ssize_t ); + ssize_t recv_udp(void *, ssize_t ); + ssize_t recv_udp_reliable(void *, ssize_t ); + ssize_t recv_tcp(void *, ssize_t ); + + void close_tcp(); + void close_udp(); + void close_udp_reliable(); + public: + XSock(xsock_role, protocol); + + void port(u_short ); // client + void ip(int ); + void dns(string ); + + XSock accept(); + void launch(); + void close(); + ssize_t send(const void *, ssize_t ); + ssize_t recv(void *, ssize_t ); + + char * getClientAddress(); + char * getServerAddress(); + + u_short get_local_port(); + u_short get_server_port(); + string get_server_dns(); + string get_server_ip(); + string get_client_dns(); + string get_client_ip(); + void dump_info(); + }; // end class + +} // end namespace + +#endif diff --git a/src/XSockTCP.cpp b/src/XSockTCP.cpp new file mode 100644 index 0000000..1d8129c --- /dev/null +++ b/src/XSockTCP.cpp @@ -0,0 +1,102 @@ + +#include "XSock.h" + +#define VERBOSE 0 +#define VERBOSETCP 0 + +using namespace std; +using namespace XSockExcept; + +namespace XSock { + + void XSock::close_tcp(){ + ::close(this->_sockFd); + } + + void XSock::launch_tcp_client(){ + + if((this->_sockFd=socket(AF_INET, SOCK_STREAM,0))==-1){ + perror("socket"); + throw eInvalidSocket(); + } + if (connect(this->_sockFd, + (struct sockaddr *)&this->_server, + this->_server_length) < 0) { + ::close(this->_sockFd); + perror("connect"); + throw eUnableToConnect(); + } + } + + void XSock::launch_tcp_server(){ + if((this->_sockFd=socket(AF_INET, SOCK_STREAM,0))==-1){ + throw eInvalidSocket(); + } + + if (bind(this->_sockFd, + (struct sockaddr*)&this->_server, + sizeof(this->_server))==-1) + { + throw eUnableToBind(); + } + /* + FD_ZERO(&this->_openSockFdSet); + FD_SET(this->_sockFd, &this->_openSockFdSet); + */ + if (listen(this->_sockFd,this->_backlog)==-1){ + throw eUnableToListen(); + } + } + + + XSock XSock::accept_tcp(){ + + XSock *nXSock = new XSock(CLIENT,this->_proto); + + if((nXSock->_sockFd = ::accept(this->_sockFd, + (struct sockaddr *) &nXSock->_client, + &nXSock->_client_length)) == -1){ + if(VERBOSETCP>=1){perror("accept");} + throw eUnableToAccept(); + } + + return *nXSock; + } + + ssize_t XSock::recv_tcp(void *bufferData, ssize_t size){ + //TODO: commenter + ssize_t p = read(this->_sockFd,bufferData,size); + if(p == -1) + throw XSockExcept::eSockUnreadable(); + return p; + } + + ssize_t XSock::send_tcp(const void *bufferData, ssize_t size){ + //TODO : commenter + ssize_t p = write(this->_sockFd,bufferData,size); + if(p == -1) + throw XSockExcept::eSockUnwritable(); + return p; + } + + string XSock::get_client_ip(){ + return string(inet_ntoa(this->_client.sin_addr)); + } + + string XSock::get_client_dns(){ + //TODO: tout + return string(""); + } + + string XSock::get_server_ip(){ + return string(inet_ntoa(this->_server.sin_addr)); + } + + string XSock::get_server_dns(){ + //TODO: tout + return string(""); + } + +} + + diff --git a/src/XSockUDP.cpp b/src/XSockUDP.cpp new file mode 100644 index 0000000..9c49b3d --- /dev/null +++ b/src/XSockUDP.cpp @@ -0,0 +1,83 @@ + +#include "XSock.h" + +// constantes utilisées dans XSock.cpp et dans XSockUDP.cpp +#define NBPORTSPUB 64512 +#define PNUMPORTPUB 1025 +#define GETPORTPUB() PNUMPORTPUB+(rand()%NBPORTSPUB) + +#define VERBGAPP 0 +#define VERBACCEPT 0 +#define VERBLAUNCHCLI 0 +#define VERBSEND 0 +#define VERBRECV 0 + + +#define VERBOSE 1 +#define ACK 0 +#define NON_ACK 1 +#define HI 2 +#define BYE 3 +#define SIZEADD 2*sizeof(u_short) + 2*sizeof(u_int) +#define SIZESTART 2*sizeof(u_short) + sizeof(u_int) +#define NBMAXTENTATIVES 16 +#define TIMERBASE 10000 + +using namespace std; +using namespace XSockExcept; + + +namespace XSock { + /* + extern u_int nbConn; + + void XSock::AddConnectionToManage(int desc){ + + }*/ + + void XSock::close_udp(){ + ::close(this->_sockFd); + } + + void XSock::launch_udp_client(){ + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_client\n\tentree dans launch_udp_client" << endl;} + if(this->_server.sin_port == htons(0)){ + throw eXSockNotReady(); + }else{ + // rien a faire... je crois + } + } + + void XSock::launch_udp_server(){ + /* TODO: choisir mono ou multi-processus */ + /* meme remarque que dans TCP */ + if((this->_sockFd=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP))==-1){ + perror("eInvalidSocket"); + throw eInvalidSocket(); + } + + if (bind(this->_sockFd, + (struct sockaddr*)&this->_server, + sizeof(this->_server))==-1) + { + perror("eUnableToBind"); + throw eUnableToBind(); + } + } + + XSock XSock::accept_udp(){ + // rien a faire + } + + ssize_t XSock::recv_udp(void *bufferData, ssize_t size){ + ssize_t p = read(this->_sockFd, bufferData, size); + // traiter les erreurs... + return p; + } + + ssize_t XSock::send_udp(const void *bufferData, ssize_t size){ + ssize_t p = write(this->_sockFd, bufferData, size); + // traiter les erreurs... + return p; + } +} diff --git a/src/XSockUDP_RELIABLE.cpp b/src/XSockUDP_RELIABLE.cpp new file mode 100644 index 0000000..dcc9171 --- /dev/null +++ b/src/XSockUDP_RELIABLE.cpp @@ -0,0 +1,531 @@ + +#include "XSock.h" + +// constantes utilisées dans XSock.cpp et dans XSockUDP_RELIABLE.cpp +#define NBPORTSPUB 64512 +#define PNUMPORTPUB 1025 +#define GETPORTPUB() PNUMPORTPUB+(rand()%NBPORTSPUB) + +#define VERBGAPP 0 +#define VERBACCEPT 0 +#define VERBLAUNCHCLI 0 +#define VERBSEND 0 +#define VERBRECV 0 + + +#define VERBOSE 1 +#define ACK 0 +#define NON_ACK 1 +#define HI 2 +#define BYE 3 +#define SIZEADD 2*sizeof(u_short) + 2*sizeof(u_int) +#define SIZESTART 2*sizeof(u_short) + sizeof(u_int) +#define NBMAXTENTATIVES 16 +#define TIMERBASE 10000 + +using namespace std; +using namespace XSockExcept; + +/* Fonction permettant de faire simplement un appel select avec un seul +* descripteur. +*/ +int uniselect(int desc, struct timeval timer){ + fd_set *rfdset = (fd_set *)malloc(sizeof(fd_set)); + bzero((char *)rfdset,sizeof(fd_set)); + //fd_set rfdset; + // initialisation des ensembles de descripteur + FD_ZERO(rfdset); + FD_SET(desc, rfdset); + return select(desc+1, rfdset, NULL, NULL, &timer); +} + + + +namespace XSock { + /* + extern u_int nbConn; + + void XSock::AddConnectionToManage(int desc){ + + }*/ + + void XSock::close_udp_reliable(){ + ::close(this->_sockFd); + } + + u_short XSock::getAvailablePortPub(){ + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\tdebut" << endl;} + this->_server.sin_port = htons(GETPORTPUB()); + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\t\tpremier port aleatoire obtenu : ";} + if(VERBGAPP==1){cout << this->_server.sin_port << endl;} + while((::bind(this->_sockFd, (struct sockaddr*)&this->_server, sizeof(this->_server))) == -1){ + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\t\t while bind" << endl;} + if(errno != EADDRINUSE){ + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\t\t bind err non! : " << endl;} + if(VERBOSE == 1){perror("bind");} + throw eUnableToBind(); + }else{ + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\t\t bind non!" << endl;} + this->_server.sin_port = htons(GETPORTPUB()); + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\t\t premier port aléatoire obtenu : " << ntohs(this->_server.sin_port) << endl;} + } + } + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\t\t fin while" << endl;} + if(VERBGAPP==1){cout << "--> getAvailablePortPub\n\treturn " << ntohs(this->_server.sin_port) << endl;} + return this->_server.sin_port; + } + + + void XSock::launch_udp_reliable_client(){ + /* par définition, le client est mono-processus */ + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\tentree dans launch_udp_reliable_client" << endl;} + if(this->_server.sin_port == htons(0)){ + throw eXSockNotReady(); + }else{ + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t" << endl;} + if((this->_sockFd=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP))==-1){ + throw eInvalidSocket(); + } + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\tdebut..." << endl;} + int fait = 0; + void *sbuffer = malloc(SIZESTART), *rbuffer = malloc(SIZESTART); + u_short *ussbuffer = (u_short *)sbuffer, *usrbuffer = (u_short *)rbuffer; + u_int *ulsbuffer = (u_int *)sbuffer, *ulrbuffer = (u_int *)rbuffer; + int srecv, sel, tentatives; + //struct sockaddr_in client; + struct timeval timer; + timer.tv_sec = 0; + timer.tv_usec = TIMERBASE; + //socklen_t* lenclient = (socklen_t*)malloc(sizeof(socklen_t)); + ussbuffer[0] = htons(HI); + ussbuffer[1] = 0; + this->_secnumrecv = rand(); + ulsbuffer[1] = htonl(this->_secnumrecv); + if(VERBLAUNCHCLI >=2){cout << "\t\tsec client : " << this->_secnumrecv << endl;} + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\tfin init" << endl;} + ::sendto(this->_sockFd, sbuffer, SIZESTART, 0, + (struct sockaddr*)&this->_server, sizeof(this->_server)); + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\tsendto1" << endl;} + tentatives = 0; + while(((tentatives < NBMAXTENTATIVES) && (fait <= 0)) + && (((sel = uniselect(this->_sockFd,timer)) == 0) || (sel == 1))) + { + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\twhile tentatives " << tentatives << endl;} + while((sel == 1 && (fait <= 0))){// il y a quelque chose à lire + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t while" << endl;} + srecv = ::recv(this->_sockFd, rbuffer, SIZESTART, 0); + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t recvfrom" << endl;} + if(VERBLAUNCHCLI >=2){printf("rbuffer : 0x%08x %08x\n",ulrbuffer[0],ulrbuffer[1]);} + if(srecv == SIZESTART){ // c'est pas trop petit + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t test taille oui!" << endl;} + if(HI == ntohs(usrbuffer[0])){ // c'est bien un message d'ouverture de connexion + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t test ack oui!" << endl;} + this->_secnumsend = ntohl(ulrbuffer[1]); + if(VERBLAUNCHCLI >=2){cout << "\n\t\t\tsec serveur : " << this->_secnumsend << endl;} + this->_server.sin_port = usrbuffer[1]; + if(VERBLAUNCHCLI >=2){cout << "\n\t\t\tport serveur : " << ntohs(this->_server.sin_port) << endl;} + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t recupe valeurs serveur port : " << ntohs(this->_server.sin_port) << endl;} + ::sendto(this->_sockFd, rbuffer, SIZESTART, 0, + (struct sockaddr*)&this->_server, sizeof(this->_server)); + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t sendto confirmation" << endl;} + timer.tv_usec+=timer.tv_usec/4; + if((sel = uniselect(this->_sockFd,timer)) == 0){ + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t plus qu'a sortir" << endl;} + fait = 10; + }else{ + timer.tv_usec = timer.tv_usec / 2; + } + }else{ // c'est pas un message d'ouverture de connexion, donc on jete. + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t test ack non!" << endl;} + } + }else{ // c'est trop petit, donc on jete. + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t test taille non!" << endl;} + } + sel = 0; + } + if((sel == 0) && (fait <= 0)){ + tentatives++; + ::sendto(this->_sockFd, sbuffer, SIZESTART, 0, + (struct sockaddr*)&this->_server, sizeof(this->_server)); + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\tresend1" << endl;} + }else{ + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\t fin while" << endl;} + } + } + if(tentatives >= NBMAXTENTATIVES){ + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\tfin while tentatives == " << tentatives << endl;} + throw eUnableToAccept(); + } + if(VERBLAUNCHCLI >=1){cout << "--> launch_udp_reliable_client\n\t\tfin while" << endl;} + this->_client.sin_addr.s_addr = this->_server.sin_addr.s_addr; + this->_client.sin_port = this->_server.sin_port; + } + } + + void XSock::launch_udp_reliable_server(){ + /* TODO: choisir mono ou multi-processus */ + /* même remarque que dans TCP */ + if((this->_sockFd=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP))==-1){ + perror("eInvalidSocket"); + throw eInvalidSocket(); + } + + if (bind(this->_sockFd, + (struct sockaddr*)&this->_server, + sizeof(this->_server))==-1) + { + perror("eUnableToBind"); + throw eUnableToBind(); + } + } + + XSock XSock::accept_udp_reliable(){ + //TODO: remplir + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\tdebut" << endl;} + XSock *nSock; + void *buffer = malloc(SIZESTART); + u_short *usbuffer = (u_short *)buffer; + u_int *ulbuffer = (u_int *)buffer; + int srecv; + struct sockaddr_in client; + struct timeval timer; + timer.tv_sec = 0; + timer.tv_usec = TIMERBASE; + socklen_t lenclient = sizeof(struct sockaddr_in); + + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\tfin init" << endl;} + while((srecv = ::recvfrom(this->_sockFd,buffer,SIZESTART, 0, + (struct sockaddr*)&client, &lenclient)) != 0){ + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\twhile recvfrom" << endl;} + if(srecv == -1) + throw eSockUnreadable(); + else { + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test srecv oui!" << endl;} + if(srecv == SIZESTART){ + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test taille oui!" << endl;} + u_short ack = ntohs(*usbuffer); + if(ack == HI){ + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test ack oui!" << endl;} + //initialisation du nouveau XSock + nSock = new XSock(CLIENT,this->_proto); + nSock->_secnumsend = ntohl(ulbuffer[1]); + if(VERBACCEPT >=2){cout << "\n\t\t\tsec client = " << nSock->_secnumsend << endl;} + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t new sock cree" << endl;} + if((nSock->_sockFd = ::socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP)) == -1){ + throw eInvalidSocket(); + } + if(VERBACCEPT <= -1){cout << "--> accept_udp_reliable\n\t nSock->_sockFd : " << nSock->_sockFd << endl;} + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test socket ok!" << endl;} + nSock->_client.sin_addr.s_addr = client.sin_addr.s_addr; + if(VERBACCEPT >=2){cout << "\n\t\t\tadresse client : " << inet_ntoa(nSock->_client.sin_addr) << endl;} + nSock->_client.sin_port = client.sin_port; + if(VERBACCEPT >=2){cout << "\n\t\t\tport client : " << ntohs(nSock->_client.sin_port) << endl;} + u_short port = nSock->getAvailablePortPub(); + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t new port ok!" << endl;} + + // prépare message avec port + numseqence + ulbuffer[0] = htonl(HI*0x10000+port); + nSock->_secnumrecv = rand(); + ulbuffer[1] = htonl(nSock->_secnumrecv); + //(u_short)buffer[sizeof(u_short) + sizeof(u_int)] = (u_short)htons(port); + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t init buffer\n\t\t\tack = " << *(u_short*)buffer;} + if(VERBACCEPT >=2){cout << "\n\t\t\tsecnum serveur = " << nSock->_secnumrecv;} + if(VERBACCEPT >=2){cout << "\n\t\t\tport serveur = " << port << endl;} + if(VERBACCEPT >=2){printf("message envoye : 0x%08x %08x ==\t ack|port : 0x%08x sec : 0x%08x\n", + ulbuffer[0],ulbuffer[1], + htonl(HI*0x10000+port), + htonl(nSock->_secnumrecv));} + + // envoie du message et attente de confirmation. + ::sendto(nSock->_sockFd, buffer, SIZESTART, 0, + (struct sockaddr*)&nSock->_client, nSock->_client_length); + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t sendto" << endl;} + void *rbuffer = malloc(SIZESTART); + u_short *usrbuffer = (u_short *)rbuffer; + u_int *ulrbuffer = (u_int *)rbuffer; + int sel,tentatives = 0; + struct sockaddr_in client2; + while((tentatives < NBMAXTENTATIVES) + && (((sel = uniselect(nSock->_sockFd,timer)) == 0) || (sel == 1))) + { + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t while tentative " << tentatives << endl;} + if(sel == 1){ + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test sel oui!" << endl;} + lenclient = sizeof(client2); + srecv = ::recvfrom(nSock->_sockFd, rbuffer, SIZESTART, 0, + (struct sockaddr*)&client2, &lenclient); + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t recvfrom" << endl;} + if((client2.sin_addr.s_addr == nSock->_client.sin_addr.s_addr) + && (client2.sin_port == nSock->_client.sin_port)) + { + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test bon client oui!" << endl;} + if((usrbuffer[0] == htons(HI)) && + (usrbuffer[1] == usbuffer[1]) && + (ulrbuffer[1] == ulbuffer[1])) + { + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test ack oui!" << endl;} + break; + } + } + }else{ + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t test sel non!" << endl;} + ::sendto(nSock->_sockFd, buffer, SIZESTART, 0, + (struct sockaddr*)&nSock->_client, nSock->_client_length); + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t sendto" << endl;} + } + tentatives++; + } + if(tentatives == NBMAXTENTATIVES){ + break; + } + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t fin while\n\t\tretour ok!" << endl;} + // on attend car en face il attend voir si on renvoie pas un message... + usleep(timer.tv_usec*2); + return *nSock;// à remplacer plus tard en renvoyant le pointeur direct + } + } + } + } + if(VERBACCEPT >=1){cout << "--> accept_udp_reliable\n\t\t probleme!!" << endl;} + throw eUnableToAccept(); + } + + ssize_t XSock::recv_udp_reliable(void *bufferData, ssize_t size){ + //TODO : le ACK est fait avec une fentre de 1 + // il y a plein de problèmes générés par ce système très incomplet. + // mettre un système de timer évolutif + u_int tentatives =16; + if(VERBRECV==1){cout << "--> recv_udp_reliable\n\tdebut" << endl;} + ssize_t p = 0; + struct timeval timer; + char *cbufferData = (char*)bufferData; + timer.tv_sec = 0; + timer.tv_usec = TIMERBASE; + ssize_t sizet = SIZEADD + size; + void *rbuffer = malloc(sizet), *sbuffer = malloc(SIZEADD); + u_int *ulrbuffer = (u_int *)rbuffer, *ulsbuffer = (u_int *)sbuffer; + u_short *usrbuffer = (u_short *)rbuffer, *ussbuffer = (u_short *)sbuffer; + char *crbuffer = (char*)rbuffer; + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\tfin init" << endl;} + if(VERBRECV>=2){ + cout << "--> recv_udp_reliable\n\t this->_sockFd = " << this->_sockFd << endl; + } + if((p = ::recv(this->_sockFd,rbuffer,sizet,0)) == -1){ + if(VERBRECV>=1){perror("XSock::recv{recv}");} + throw eSockUnreadable(); + } + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t\trecv ok! p = " << p << endl;} + p-=SIZEADD; + if(VERBRECV>=2){cout << "--> recv_udp_reliable\n\t\t p-SIZEADD = " << p << endl;} + int renv = 0, recevoir = 0, env = 0; + tentatives = 16; + while((tentatives > 0) && (p >= 0)){ + tentatives--; + switch (usrbuffer[0]){ + case ACK : + { + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t ack == ack alors qu'on est dans le recv" << endl;} + + recevoir = 10; + break; + } + case NON_ACK : + { + if((this->_secnumrecv > ntohl(ulrbuffer[1])) || (this->_secnumrecv < ntohl(ulrbuffer[1]))){ + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t secnum >< recu" << endl;} + ussbuffer[0] = htons(ACK); + ulsbuffer[1] = htonl(this->_secnumrecv); + renv = 10; + recevoir = 10; + }else{ + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t secnum == recu (= " << this->_secnumrecv << ")" << endl;} + ussbuffer[0] = htons(ACK); + this->_secnumrecv+=p; + ulsbuffer[1] = htonl(this->_secnumrecv); + if(VERBRECV>=2){cout << "--> recv_udp_reliable\n\t nouv secnum = " << this->_secnumrecv << endl;} + env = 10; + } + break; + } + case BYE : + {//fermeture de la connexion + ::sendto(this->_sockFd, rbuffer, SIZEADD, 0, (struct sockaddr*)&this->_client, this->_client_length); + while((uniselect(this->_sockFd,timer)) == 1){ + ::sendto(this->_sockFd, rbuffer, SIZEADD, 0, (struct sockaddr*)&this->_client, this->_client_length); + } + throw eConnectionClosedByPeer(); + break; + } + default : + { + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t ack inconnu ou HI en pleine connection..." << endl;} + throw eSockUnreadable(); + } + } + if(renv == 10){ + ::sendto(this->_sockFd, sbuffer, SIZEADD, 0, (struct sockaddr*)&this->_client, this->_client_length); + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t resend data" << endl;} + } + if(recevoir == 10){ + if((p = ::recv(this->_sockFd,rbuffer,sizet,0)) == -1){ + if(VERBRECV>=1){perror("XSock::recv{recv}");} + throw eSockUnreadable(); + } + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t\t recv ok! p = " << p << endl;} + p-=SIZEADD; + } + if(env == 10){ + ::sendto(this->_sockFd, sbuffer, SIZEADD, 0, (struct sockaddr*)&this->_client, this->_client_length); + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t send ack" << endl;} + break; + } + } + if(tentatives==0){ + throw eConnectionClosedByPeer(); + } + //recopie des données + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\trempli bufferData" << endl;} + for(int i = 0;((i < p) || (i < size)); i++){ + cbufferData[i] = crbuffer[i+SIZEADD]; + if(VERBRECV>=3){printf("%02x -> %02x\n", crbuffer[i+SIZEADD], cbufferData[i]);} + } + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\t fin while" << endl;} + timer.tv_usec+=timer.tv_usec/2; + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\ttimer = "< 0) && ((uniselect(this->_sockFd, timer)) == 1)){ + tentatives--; + if((p = ::recv(this->_sockFd,rbuffer,sizet,0)) == -1){ + if(VERBRECV>=1){perror("XSock::recv{recv}");} + throw eSockUnreadable(); + } + if(ulrbuffer[1] == this->_secnumrecv){ + if(VERBRECV>=1){cout <<"--> recv_udp_reliable\n\t recu nouvelles donnees avec bon ack recv. on sort"<_sockFd, sbuffer, SIZEADD, 0, (struct sockaddr*)&this->_client, this->_client_length); + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\tresend ack" << endl;} + if(VERBRECV>=1){cout << "--> recv_udp_reliable\n\ttimer = "<=1){cout << "--> recv_udp_reliable\n\treturning..." << endl;} + //usleep(timer.tv_usec); + return p; + } + + ssize_t XSock::send_udp_reliable(const void *bufferData, ssize_t size){ + //TODO : mettre un système de timer évolutif + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\tdebut" << endl;} + struct timeval timer; + u_int tentatives = 16; + char *cbufferData = (char *)bufferData; + timer.tv_sec = 0; + timer.tv_usec = TIMERBASE; + int sel; + //--- + ssize_t p = 0, sizet = size+SIZEADD, srecv; + void *sbuffer = malloc(sizet), *rbuffer = malloc(SIZEADD); + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\tpreparing buffer of "<=1){cout << "--> send_udp_reliable\n\tfin init" << endl;} + for(int i = 0; i < size; i++){ + csbuffer[i+SIZEADD] = cbufferData[i]; + } + ussbuffer[0] = htons(NON_ACK); + ulsbuffer[1] = htonl(this->_secnumsend); + ulsbuffer[2] = htonl(this->_secnumrecv); + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\tfin prepare sbuffer with secnum = " << this->_secnumsend << endl;} + if(VERBSEND>=2){cout << "size of data to send : " << size << endl;} + if(VERBSEND>=3){ + cout << "data to send :" << endl; + for(int i = 0; i < sizet;i++){ + printf("%02x ", (char)csbuffer[i]); + } + } + srecv=0; + p = ::sendto(this->_sockFd, sbuffer, sizet, 0, (struct sockaddr*)&this->_client, this->_client_length); + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\tsend" << endl;} + if(VERBSEND>=2){cout << "size of data sent : " << (p-SIZEADD) << endl;} + tentatives = 16; + while((tentatives > 0) && (sel = uniselect(this->_sockFd,timer)) == 0){ + tentatives--; + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t resend data" << endl;} + p = ::sendto(this->_sockFd, sbuffer, sizet, 0, (struct sockaddr*)&this->_client, this->_client_length); + } + if(tentatives==0){ + throw eConnectionClosedByPeer(); + } + p-=SIZEADD; + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t fin while" << endl;} + if(sel == -1){ + if(VERBSEND>=1){perror("XSock::send_udp_reliable{sel}");} + throw eSockUnreadable(); + } + if((srecv = ::recv(this->_sockFd, rbuffer, SIZEADD,0)) == -1){ + if(VERBSEND>=1){perror("XSock::send_udp_reliable{recv}");} + throw eSockUnreadable(); + } + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\trecv ok!" << endl;} + if(VERBSEND>=2){cout << "--> send_udp_reliable\n\t size = " << srecv << endl;} + if(VERBSEND>=2){cout << "--> send_udp_reliable\n\t ack = " << ntohs(usrbuffer[0]) << endl;} + if(VERBSEND>=2){cout << "--> send_udp_reliable\n\t sec = " << ntohl(ulrbuffer[1]) << endl;} + u_int secawaited = this->_secnumsend + p; + if(VERBSEND>=2){cout << "--> send_udp_reliable\n\t sec awaited = " << secawaited << endl;} + tentatives = 16; + while((tentatives > 0) && ((srecv != SIZEADD) || (ntohs(usrbuffer[0]) != ACK) || (secawaited != ntohl(ulrbuffer[1])))) + { + tentatives--; + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t while" << endl;} + if(srecv == SIZEADD){ + if(ntohs(usrbuffer[0]) == NON_ACK){ + // on remarque que si le message envoyé continet le ack du message précédent + // ie this->_secnumsend == ulrbuffer[2] alors c'est comme un acquittement + // on drop tout de meme le paquet. + //if(secawaited == ulrbuffer[2]){ + // if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t acked with send action" << endl;} + // this->_secnumsend =secawaited; + // return p; + //} + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t dead lock" << endl;} + throw eDeadLock(); + } + } + p = ::sendto(this->_sockFd, sbuffer, sizet, 0, (struct sockaddr*)&this->_client, this->_client_length); + while((sel = uniselect(this->_sockFd,timer)) == 0){ + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t resend data" << endl;} + p = ::sendto(this->_sockFd, sbuffer, sizet, 0, (struct sockaddr*)&this->_client, this->_client_length); + } + p-=SIZEADD; + if((srecv = ::recv(this->_sockFd, rbuffer, SIZEADD,0)) == -1){ + if(VERBSEND>=1){perror("XSock::send_udp_reliable{recv}");} + throw eSockUnreadable(); + } + } + if(tentatives==0){ + throw eConnectionClosedByPeer(); + } + if(srecv == SIZEADD){ + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t verif taille ok!" << endl;} + if(ntohs(usrbuffer[0]) == ACK){// on est content + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t verif ACK ok!" << endl;} + if(this->_secnumsend + p == ntohl(ulrbuffer[1])){ + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t verif secnum ok! returning..." << endl;} + //c'est bon ! + usleep(timer.tv_usec); + this->_secnumsend+=p; + return p; + } + } + } + //impossible d'arriver ici normalement + if(VERBSEND>=1){cout << "--> send_udp_reliable\n\t soucis!!!" << endl;} + + + return p; + } +} diff --git a/src/XSock_errors.h b/src/XSock_errors.h new file mode 100644 index 0000000..c20881f --- /dev/null +++ b/src/XSock_errors.h @@ -0,0 +1,33 @@ +#ifndef _XSOCK_ERRORS +#define _XSOCK_ERRORS 1 + +namespace XSockExcept { + class eXSockExcept { }; + class eInvalidSocket : eXSockExcept { }; + class eUnknownProtocol : eXSockExcept { }; + class eUnableToListen : eXSockExcept { }; + class eUnableToConnect : eXSockExcept { }; + class eUnableToAccept : eXSockExcept { }; + class eUnableToBind : eXSockExcept { }; + class eSockUnreadable : eXSockExcept { }; + class eSockUnwritable : eXSockExcept { }; + class eUnknownXSockRole : eXSockExcept { }; + class eUnableToResolveName : eXSockExcept { }; + class eXSockNotReady : eXSockExcept { }; + class eConnectionClosedByPeer : eXSockExcept { }; + class eDeadLock : eXSockExcept { }; + class eUnableToLock : eXSockExcept { }; + class eUnableToUnlock : eXSockExcept { }; + class eUnableToCloseFile : eXSockExcept { }; + class eUnableToOpenFile : eXSockExcept { }; + class eUnableToStatFile : eXSockExcept { }; + class eUnableToOpen2ndFile : eXSockExcept { }; + class eUnableToCreateFile : eXSockExcept { }; + class eUnableToDeleteFile : eXSockExcept { }; + class eUnableToReadFile : eXSockExcept { }; + class eUnableToWriteFile : eXSockExcept { }; + /* définition des exceptions ici */ + +} + +#endif diff --git a/src/XSock_global.h b/src/XSock_global.h new file mode 100644 index 0000000..0e2ed6e --- /dev/null +++ b/src/XSock_global.h @@ -0,0 +1,35 @@ +#ifndef _XSOCK_GLOBAL +#define _XSOCK_GLOBAL 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* spécifie le nombre maximum de demandes de connexion en attente d'être acceptées. */ + +#define XSOCK_MESSAGES_LENGTH 128 +#define XSOCK_CHUNK_LENGTH 4096 +#define XSOCK_INVALID_SOCKET -1 +#define MAXGAUCHE(X,Y) (X