Mercurial > code
diff C++/Socket.h @ 170:fd138f2a9773
Add C++ portable sockets
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 10 Sep 2013 15:17:56 +0200 |
parents | |
children | 18ad49172e6c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/C++/Socket.h Tue Sep 10 15:17:56 2013 +0200 @@ -0,0 +1,285 @@ +/* + * Socket.h -- portable C++ socket wrappers + * + * Copyright (c) 2013, David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SOCKET_H_ +#define _SOCKET_H_ + +#include <exception> +#include <memory> +#include <string> + +#if defined(_WIN32) +# include <WinSock2.h> +# include <WS2tcpip.h> +#else +# include <sys/ioctl.h> +# include <sys/socket.h> +# include <sys/types.h> + +# include <arpa/inet.h> + +# include <netinet/in.h> + +# include <fcntl.h> +# include <netdb.h> +# include <unistd.h> + +# define ioctlsocket(s, p, a) ::ioctl(s, p, a) +# define closesocket(s) ::close(s) + +# define gai_strerrorA gai_strerror + +# define INVALID_SOCKET -1 +# define SOCKET_ERROR -1 +#endif + +class SocketAddress; + +/** + * @class SocketError + * @brief socket error reporting + * + * This class is mainly used in all socket operations that may fail. + */ +class SocketError : public std::exception +{ +private: + std::string m_error; + +public: + SocketError(const std::string &error); + + virtual const char * what(void) const throw(); +}; + +/** + * @class Socket + * @brief socket abstraction + * + * This class is a big wrapper around sockets functions but portable, + * there is some functions that helps for getting error reporting. + */ +class Socket +{ +public: +#if defined(_WIN32) + typedef SOCKET Type; + typedef const char * ConstArg; + typedef char * Arg; +#else + typedef int Type; + typedef const void * ConstArg; + typedef void * Arg; +#endif + +protected: + Socket::Type m_socket; + +public: + /** + * To be called before any socket operation. + */ + static void init(); + + /** + * Get the last socket system error. + * + * @return a string message + */ + static std::string getLastSysError(); + + /** + * To be called before exiting. + */ + static void finish(); + + /** + * Default constructor. + */ + Socket(); + + /** + * Constructor to create a new socket. + * + * @param domain the domain + * @param type the type + * @param protocol the optional protocol + * @throw SocketError on error + */ + Socket(int domain, int type, int protocol = 0); + + /** + * Constructor with a socket already opened. + * + * @param sock the socket + */ + Socket(Socket::Type sock); + + /** + * Default destructor. + */ + virtual ~Socket(); + + /** + * Get the socket. + * + * @return the socket + */ + Type getSocket() const; + + /** + * Set an option for the socket. + * + * @param level the setting level + * @param name the name + * @param arg the value + * @param argLen the argument length + * @throw SocketError on error + */ + void set(int level, int name, const void *arg, unsigned argLen); + + /** + * Enable or disable blocking mode. + * + * @param block the mode + */ + void blockMode(bool block = true); + + /** + * Bind the socket. + * + * @param location a IP or Unix location + * @throw SocketError error + */ + void bind(const SocketAddress &address); + + /** + * Try to connect to the specific address + * + * @param addr the address + * @throw SocketError on error + */ + void connect(const SocketAddress &address); + + /** + * Accept a client without getting its info. + * + * @return a client ready to use + * @throw SocketError on error + */ + Socket accept(); + + /** + * Accept a client. + * + * @param info the optional client info + * @return a client ready to use + * @throw SocketError on error + */ + Socket accept(SocketAddress &info); + + /** + * Listen to a specific number of pending connections. + * + * @param max the max number of clients + * @throw SocketError on error + */ + void listen(int max); + + /** + * Receive some data. + * + * @param data the destination pointer + * @param dataLen max length to receive + * @return the number of bytes received + * @throw SocketError on error + */ + unsigned recv(void *data, unsigned dataLen); + + /** + * Send some data. + * + * @param data the data to send + * @param dataLen the data length + * @return the number of bytes sent + * @throw SocketError on error + */ + unsigned send(const void *data, unsigned dataLen); + + /** + * Send a message as a string. + * + * @param message the message + * @return the number of bytes sent + * @throw SocketError on error + */ + unsigned send(const std::string &message); + + /** + * Receive from a connection-less socket without getting + * client information. + * + * @param data the destination pointer + * @param dataLen max length to receive + * @return the number of bytes received + * @throw SocketError on error + */ + unsigned recvfrom(void *data, unsigned dataLen); + + /** + * Receive from a connection-less socket and get the client + * information. + * + * @param data the destination pointer + * @param dataLen max length to receive + * @param info the client info + * @return the number of bytes received + * @throw SocketError on error + */ + unsigned recvfrom(void *data, unsigned dataLen, SocketAddress &info); + + /** + * Send some data to a connection-less socket. + * + * @param data the data to send + * @param dataLen the data length + * @param address the address + * @return the number of bytes sent + * @throw SocketError on error + */ + unsigned sendto(const void *data, unsigned dataLen, const SocketAddress &info); + + /** + * Send a message to a connection-less socket. + * + * @param message the message + * @param address the address + * @return the number of bytes sent + * @throw SocketError on error + */ + unsigned sendto(const std::string &message, const SocketAddress &info); + + /** + * Close the socket. + */ + void close(); +}; + +bool operator==(const Socket &s1, const Socket &s2); + +#endif // !_SOCKET_H_