#ifndef SOCKET_H #define SOCKET_H #ifdef WIN32 /* si vous êtes sous Windows */ #include #elif defined (linux) /* si vous êtes sous Linux */ #include #include #include #include #include /* close */ #include /* gethostbyname */ #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define closesocket(s) close(s) typedef int SOCKET; typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR; typedef struct in_addr IN_ADDR; #include #else /* sinon vous êtes sur une plateforme non supportée */ #error not defined for this platform #endif #include #include #include class SocketError { public: SocketError(const std::string& s, const std::string& t) : error(s), type(t){} virtual ~SocketError(){} std::string error; std::string type; }; #define DefineSocketError(__Err__) class __Err__ : public SocketError{ public: __Err__(const std::string& e, const std::string& t) : SocketError(e, t){} ~__Err__(){} }; DefineSocketError(ConnectSocketError) DefineSocketError(FileSocketNotFoundError) DefineSocketError(SendSocketError) DefineSocketError(RecieveSocketError) DefineSocketError(AcceptSocketError) DefineSocketError(BindSocketError) DefineSocketError(ListenSocketError) DefineSocketError(HostSocketError) DefineSocketError(OptSocketError) #ifndef THROW #define THROW(__ERR__, __MSG__) {std::ostringstream os; os << #__ERR__<< " : " << __MSG__ <<"\n"; std::cerr << os.str(); throw __ERR__(os.str(), #__ERR__);} #endif class _AbsSocket { public: enum SocketType { INET, UNIX, STDIO } ; _AbsSocket(SocketType); virtual ~_AbsSocket(); virtual void close(); virtual bool is_open(); protected: SocketType m_type; SOCKET m_sock; bool m_is_open; }; class ISocket : public std::istream, public std::ostream { public: virtual ~ISocket(){} virtual void write(const void* data, int size)=0; virtual int read(void* data, int n, bool blocking)=0; virtual ISocket& putc(int c) {write(&c,1); return *(ISocket*)this;} virtual void write(const std::string& data){write(data.c_str(), data.size());} virtual int read(void* data, int n){return read(data,n,false);}; virtual int readc(){int c; return (read(&c,1)==1)?c:-1;} virtual std::string& readline(std::string&); virtual _AbsSocket::SocketType get_type() const =0; virtual void close()=0; virtual bool is_open()=0; }; class Socket : public _AbsSocket, public ISocket { public: Socket(SocketType t) : _AbsSocket(t){} Socket(SocketType type, SOCKET client) : Socket(type){m_sock=client; m_is_open=true;} virtual ~Socket(){} virtual void write(const void* data, int size); virtual int read(void* data, int n, bool blocking); virtual SocketType get_type() const {return m_type;} virtual void close(){_AbsSocket::close();}; virtual bool is_open(){return _AbsSocket::is_open();} }; class InetSocket : public Socket { public: InetSocket() : Socket(INET){} InetSocket(SOCKET sock) : Socket(INET, sock){} virtual ~InetSocket(){} virtual bool connect(const std::string& addr, int port); virtual Socket::SocketType get_type() const {return Socket::INET;} protected: std::string m_hostname; int m_port; }; class UnixSocket : public Socket { public: UnixSocket() : Socket(UNIX){} virtual ~UnixSocket(){} virtual bool connect(const std::string& addr); virtual Socket::SocketType get_type() const {return Socket::UNIX;} protected: std::string m_hostname; int m_port; }; class IAbsServer { public: virtual ~IAbsServer(){} virtual ISocket* accept()=0; virtual Socket::SocketType get_type() const=0; }; class InetServer : public _AbsSocket, public IAbsServer { public: InetServer(); virtual ~InetServer(){} virtual void listen(int port); virtual ISocket* accept(); virtual Socket::SocketType get_type() const {return Socket::INET;} }; class UnixServer : public _AbsSocket, public IAbsServer { public: UnixServer(); virtual ~UnixServer(); virtual void listen(const std::string& path){return listen(path, true);} virtual void listen(const std::string& path, bool); virtual ISocket* accept(); virtual Socket::SocketType get_type() const {return Socket::UNIX;} protected: std::string m_path; }; class StdioSocket : public ISocket { public: StdioSocket(int first){m_first=first;} virtual ~StdioSocket(){} virtual void write(const void* data, int size); virtual int read(void* data, int n, bool blocking); virtual Socket::SocketType get_type() const {return Socket::STDIO;} virtual void close(){}; virtual bool is_open(){return false;} public: int m_first; }; class StdioServer : public IAbsServer { public: StdioServer() {} virtual ~StdioServer(){} virtual ISocket* accept(); virtual Socket::SocketType get_type() const {return Socket::STDIO;} }; #endif // SOCKET_H