#include #include #include #include #include #include #include #include #include "String.h" #include "Socket.h" #include "Exceptions.h" #include "config.h" #include "Input.h" #include "Output.h" Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false) { if (GetHandle() < 0) { throw GeneralException(_("Error creating socket.")); } } Socket::Socket(int h) : Handle(h), connected(true), listening(false) { } String Socket::GetName(void) { return String("socket"); } bool Socket::IsConnected(void) { return connected; } bool Socket::IsListening(void) { return listening; } bool Socket::CanRead(void) { return connected; } bool Socket::CanWrite(void) { return connected; } /***********************************************\ * Toute la suite n'est pas à décrire. Consulter * * plutôt un document décrivant les sockets. * \***********************************************/ bool Socket::SetLocal(String vhost, int port) { struct hostent * localhostent; struct in_addr localhostaddr; struct sockaddr_in localsocketaddr; memset((void *)&localhostaddr, 0, sizeof(localhostaddr)); if (vhost.strlen() != 0) { if ((localhostent = gethostbyname(vhost.to_charp()))) { memcpy((void *)&localhostaddr, localhostent->h_addr, sizeof(localhostaddr)); } else { return false; } } else { localhostaddr.s_addr = htonl(INADDR_ANY); } memset(&localsocketaddr, 0, sizeof(struct sockaddr_in)); localsocketaddr.sin_family = AF_INET; localsocketaddr.sin_addr = localhostaddr; localsocketaddr.sin_port = htons(port); if (bind(GetHandle(), (struct sockaddr *) &localsocketaddr, sizeof(localsocketaddr)) < 0) { return false; } else { return true; } } bool Socket::Connect(String host, int port) { struct hostent * remotehostent; struct sockaddr_in remotesocketaddr; if (!listening && !connected) { cerr << " - Resolving '" << host << "'..." << endl; if (!(remotehostent = gethostbyname(host.to_charp()))) { return false; } remotesocketaddr.sin_family = AF_INET; remotesocketaddr.sin_port = htons(port); bcopy(remotehostent->h_addr, &remotesocketaddr.sin_addr, remotehostent->h_length); cerr << " - Connecting to port " << port << " ..." << endl; if (!connect(GetHandle(), (struct sockaddr *)&remotesocketaddr, sizeof(remotesocketaddr))) { cerr << " - Connected." << endl; connected = true; } else { cerr << " - Error connecting: " << strerror(errno) << endl; } } return connected; } bool Socket::Listen(void) { if (!listening && !connected) { if (!listen(GetHandle(), 10)) { listening = true; } } return listening; } Socket Socket::Accept(void) throw (GeneralException) { struct sockaddr inaddr; socklen_t inlen = sizeof(inaddr); int h; if ((h = accept(GetHandle(), &inaddr, &inlen)) < 0) { throw GeneralException(_("Failed accepting.")); } else { return Socket(h); } } int Socket::GetPort() { int r; struct sockaddr_in localsocketaddr; socklen_t locallen = sizeof(localsocketaddr); if (getsockname(GetHandle(), (struct sockaddr *) &localsocketaddr, &locallen)) { return -1; } r = ntohs(localsocketaddr.sin_port); return r; }