#ifdef OSF1 #define _XOPEN_SOURCE 500 #endif #include "swrapsock.h" #include "sopnamsp.h" #include #include #include #include #include #include #include #include /*! \class SOPHYA::Socket \ingroup SysTools \brief Base class for server and client sockets. The class Socket is not intended for direct use. Only the derived classes ServerSocket and ClientSocket should be used. */ /* --Methode-- */ Socket::Socket(int s) { skt = s; tstart = tlast = (long)time(NULL); totsnd = totrcv = 0; dts = dtr = 0; nbbs = nbbr = 0; lstnbb = 0; lstdt = 0; errcnt = 0; } /* --Methode-- */ /* --- A faire plus tard ... Socket::Socket(Socket const & a) { skt = a.skt; tstart = a.tstart; tlast = a.tlast; totsnd = a.totsnd; totrcv = a.totrcv; dts = a.dts; dtr = a.dtr; nbbs = a.nbbs; nbbr = a.nbbr; lstnbb = a.lstnbb; lstdt = a.lstdt; errcnt = a.errcnt; } */ /* --Methode-- */ Socket::~Socket() { Close(); } /* --Methode-- */ size_t Socket::Send(const char * buff, size_t len, int flag) { ssize_t rc; rc = send(skt, buff, len, flag); if (rc > 0) { // tlast = (long)time(NULL); totsnd += rc; return(rc); } else return 0; } /* --Methode-- */ size_t Socket::Receive(char * buff, size_t len, int flag) { ssize_t rc; // int fromlen = 0; bool encore = true; while (encore) { rc = recv(skt, buff, len, flag); // rc = recvfrom(skt, buff, len, flag, NULL, &fromlen); if ((rc < 1) && (errno == EAGAIN)) usleep(20000); else encore = false; } if (rc > 0) { // tlast = (long)time(NULL); totrcv += rc; return(rc); } else return 0; } // extern int errno; /* --Methode-- */ int Socket::Close() { if (skt<0) return 0; int rc=-1; rc = shutdown(skt, SHUT_RDWR); if(rc < 0) cout << "Socket::Close() Erreur: Pb shutdown() ErrNo=" << errno << endl; rc = close(skt); if(rc < 0) cout << "Socket::Close() Erreur: Pb close() ErrNo=" << errno << endl; skt = -1; return(0); } /*! \class SOPHYA::ServerSocket \ingroup SysTools \brief Socket wrapper class for the server side */ /* --Methode-- */ ServerSocket::ServerSocket(int port, int nconmax) : Socket() { int s,rc; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { cout << "ServerSocket() Pb socket() ErrNo=" << errno << endl; throw SocketException("ServerSocket() Pb socket()"); } skt = s; if (nconmax <= 1) nconmax = 1; NConMax = nconmax; nclitot = 0; portid = port; ipskt.sin_family = AF_INET; ipskt.sin_port = htons(port); ipskt.sin_addr.s_addr = INADDR_ANY; /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */ rc = bind(skt, (struct sockaddr *)(&ipskt), sizeof(ipskt)); if (rc < 0) { Close(); cout << "ServerSocket() Pb bind() ErrNo=" << errno << endl; throw SocketException("ServerSocket() Pb bind()"); } } /* --Methode-- */ Socket ServerSocket::WaitClientConnection() { int rc,s,len; struct sockaddr_in cli; rc = listen(skt, NConMax); if (rc < 0) { cout << "ServerSocket::WaitClientConnection() Pb listen() ErrNo=" << errno << endl; throw SocketException("ServerSocket::WaitClientConnection() Pb listen()"); } /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */ socklen_t sl = sizeof(cli); s = accept(skt, (struct sockaddr *)(&cli), &sl); if(s < 0) { cout << "ServerSocket::WaitClientConnection() Pb accpet() ErrNo=" << errno << endl; throw SocketException("ServerSocket::WaitClientConnection() Pb accept()"); } nclitot++; return Socket(s); } /*! \class SOPHYA::ClientSocket \ingroup SysTools \brief Socket wrapper class for the client side */ /* --Methode-- */ ClientSocket::ClientSocket(string const& srvname, int port) : Socket() { InitConnection(srvname.c_str(), port); } /* --Methode-- */ ClientSocket::ClientSocket(const char* srvname, int port) : Socket() { InitConnection(srvname, port); } /* --Methode-- */ void ClientSocket::InitConnection(const char* name, int port) { struct hostent *server; int s,rc; #if defined(Linux) || defined(linux) typedef unsigned long in_addr_t; #endif in_addr_t inad; server = NULL; /* Try to find out if this is a known machine name */ server = gethostbyname(name); if(!server) { /* Try it as an internet address a.b.c.d */ /* inad = inet_addr(name); if(inad == INADDR_NONE) { cout << "ClientSocket() Host identification failed inet_addr(" << name << ")" << endl; throw SocketException("ClientSocket() Host identification failed "); } */ server = gethostbyaddr(name, strlen(name), AF_INET); } if(!server) { cout << "ClientSocket() Host identification failed (2) for" << name << endl; throw SocketException("ClientSocket() Host identification failed (2)"); } ipskt.sin_family = AF_INET; ipskt.sin_port = htons(port); memcpy(&(ipskt.sin_addr), server->h_addr, server->h_length); s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { cout << "ClientSocket() Erreur: Pb socket() ErrNo=" << errno << endl; throw SocketException("ClientSocket() Erreur: Pb socket()"); } skt = s; portid = port; /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */ rc = connect(skt, (struct sockaddr *)(&ipskt), sizeof(struct sockaddr_in)); if (rc < 0) { cout << "ClientSocket() Erreur: Pb connect() ErrNo=" << errno << endl; Close(); throw SocketException("ClientSocket() Erreur: Pb connect()"); } }