#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; } size_t Socket::WriteFile(Output & o) { char c; size_t s = 0; while (!IsClosed()) { s += read(&c, 1); o.write(&c, 1); } return s; } size_t Socket::ReadFile(Input & i) { char c; size_t s = 0; while (!i.IsClosed()) { s += i.read(&c, 1); write(&c, 1); } return s; } /***********************************************\ * 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) { 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); if(connect(GetHandle(), (struct sockaddr *)&remotesocketaddr, sizeof(remotesocketaddr)) < 0) { connected = true; } } return connected; } bool Socket::Listen(void) { if (!listening && !connected) { if (listen(GetHandle(), 10)) { listening = true; } } return listening; } Socket Socket::Accept(void) { struct sockaddr inaddr; socklen_t inlen = sizeof(inaddr); int h; if ((h = accept(GetHandle(), &inaddr, &inlen)) < 0) { return Socket(); } else { return Socket(h); } }