Mercurial > code
changeset 317:890729b8cb60
Reimplement SocketError and add a new Timeout code
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 04 Mar 2015 13:45:56 +0100 |
parents | 4c0af1143fc4 |
children | 68ae6d7dea1f |
files | C++/Socket.cpp C++/Socket.h C++/SocketAddress.cpp C++/SocketListener.cpp C++/SocketTcp.cpp C++/SocketUdp.cpp |
diffstat | 6 files changed, 125 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/Socket.cpp Tue Mar 03 18:48:54 2015 +0100 +++ b/C++/Socket.cpp Wed Mar 04 13:45:56 2015 +0100 @@ -69,6 +69,31 @@ } /* -------------------------------------------------------- + * SocketError class + * -------------------------------------------------------- */ + +SocketError::SocketError(Code code, std::string function) + : m_code(code) + , m_function(std::move(function)) + , m_error(Socket::syserror()) +{ +} + +SocketError::SocketError(Code code, std::string function, int error) + : m_code(code) + , m_function(std::move(function)) + , m_error(Socket::syserror(error)) +{ +} + +SocketError::SocketError(Code code, std::string function, std::string error) + : m_code(code) + , m_function(std::move(function)) + , m_error(std::move(error)) +{ +} + +/* -------------------------------------------------------- * Socket class * -------------------------------------------------------- */ @@ -82,7 +107,7 @@ m_handle = ::socket(domain, type, protocol); if (m_handle == Invalid) - throw SocketError(); + throw SocketError(SocketError::System, "socket"); } void Socket::bind(const SocketAddress &address) @@ -91,7 +116,7 @@ const auto addrlen = address.length(); if (::bind(m_handle, reinterpret_cast<const sockaddr *>(&sa), addrlen) == Error) - throw SocketError("bind", Socket::syserror(), errno); + throw SocketError(SocketError::System, "bind"); m_state = SocketState::Bound; } @@ -121,12 +146,12 @@ flags |= O_NONBLOCK; if (fcntl(m_handle, F_SETFL, flags) == Error) - throw SocketError("setBlockMode", Socket::syserror(), errno); + throw SocketError(SocketError::System, "setBlockMode"); #else unsigned long flags = (block) ? 0 : 1; if (ioctlsocket(m_handle, FIONBIO, &flags) == Error) - throw SocketError("setBlockMode", Socket::syserror(), WSAGetLastError()); + throw SocketError(SocketError::System, "setBlockMode"); #endif }
--- a/C++/Socket.h Tue Mar 03 18:48:54 2015 +0100 +++ b/C++/Socket.h Wed Mar 04 13:45:56 2015 +0100 @@ -69,6 +69,10 @@ class SocketAddress; +/** + * @class SocketError + * @brief Base class for sockets error + */ class SocketError : public std::exception { public: enum Code { @@ -80,12 +84,38 @@ }; Code m_code; + std::string m_function; std::string m_error; - template <typename... Args> - inline SocketError(const Args&... args) + /** + * Constructor that use the last system error. + * + * @param code which kind of error + * @param function the function name + */ + SocketError(Code code, std::string function); + + /** + * Constructor that use the system error set by the user. + * + * @param code which kind of error + * @param function the function name + * @param error the error + */ + SocketError(Code code, std::string function, int error); + + /** + * Constructor that set the error specified by the user. + * + * @param code which kind of error + * @param function the function name + * @param error the error + */ + SocketError(Code code, std::string function, std::string error); + + inline const std::string &function() const noexcept { - + return m_function; } inline Code code() const noexcept @@ -93,17 +123,23 @@ return m_code; } - const char *what() const noexcept { + const char *what() const noexcept + { return "Error failure"; } }; +/** + * @enum SocketState + * @brief Category of error + */ enum class SocketState { Opened, ///!< Socket is opened Closed, ///!< Socket has been closed Bound, ///!< Socket is bound to address Connected, ///!< Socket is connected to an end point - Disconnected ///!< Socket is disconnected + Disconnected, ///!< Socket is disconnected + Timeout ///!< Timeout has occured in a waiting operation }; /** @@ -254,7 +290,7 @@ #else if (setsockopt(m_handle, level, name, (Socket::ConstArg)&arg, sizeof (arg)) < 0) #endif - throw SocketError("set", syserror(), errno); + throw SocketError(SocketError::System, "set"); } /** @@ -275,7 +311,7 @@ #else if (getsockopt(m_handle, level, name, (Socket::Arg)&desired, &size) < 0) #endif - throw SocketError("get", syserror(), errno); + throw SocketError(SocketError::System, "get"); std::memcpy(&result, &desired, size);
--- a/C++/SocketAddress.cpp Tue Mar 03 18:48:54 2015 +0100 +++ b/C++/SocketAddress.cpp Wed Mar 04 13:45:56 2015 +0100 @@ -56,7 +56,7 @@ auto error = getaddrinfo(host.c_str(), std::to_string(port).c_str(), &hints, &res); if (error != 0) - throw SocketError("getaddrinfo", gai_strerror(error), error); + throw SocketError(SocketError::System, "getaddrinfo", gai_strerror(error)); std::memcpy(&m_addr, res->ai_addr, res->ai_addrlen); m_addrlen = res->ai_addrlen;
--- a/C++/SocketListener.cpp Tue Mar 03 18:48:54 2015 +0100 +++ b/C++/SocketListener.cpp Wed Mar 04 13:45:56 2015 +0100 @@ -78,7 +78,7 @@ auto result = selectMultiple(ms); if (result.size() == 0) { - throw SocketError("select", "No socket found", 0); + throw SocketError(SocketError::System, "select", "No socket found"); } return result[0]; @@ -116,15 +116,10 @@ auto error = ::select(max + 1, &readset, &writeset, nullptr, towait); if (error == Socket::Error) { -#if defined(_WIN32) - throw SocketError("select", Socket::syserror(), WSAGetLastError()); -#else - throw SocketError("select", Socket::syserror(), errno); -#endif + throw SocketError(SocketError::System, "select"); } - if (error == 0) { - throw SocketError("select"); + throw SocketError(SocketError::Timeout, "select", "Timeout while listening"); } std::vector<SocketStatus> sockets; @@ -246,13 +241,9 @@ { auto result = poll(m_fds.data(), m_fds.size(), ms); if (result == 0) - throw SocketError("select"); + throw SocketError(SocketError::Timeout, "select", "Timeout while listening"); if (result < 0) -#if defined(_WIN32) - throw SocketError("poll", Socket::syserror(), WSAGetLastError()); -#else - throw SocketError("poll", Socket::syserror(), errno); -#endif + throw SocketError(SocketError::System, "poll"); for (auto &fd : m_fds) { if (fd.revents != 0) { @@ -260,21 +251,17 @@ } } - throw SocketError("select", "No socket found", 0); + throw SocketError(SocketError::System, "select", "No socket found"); } std::vector<SocketStatus> selectMultiple(int ms) override { auto result = poll(m_fds.data(), m_fds.size(), ms); if (result == 0) { - throw SocketError("select"); + throw SocketError(SocketError::Timeout, "select", "Timeout while listening"); } if (result < 0) { -#if defined(_WIN32) - throw SocketError("poll", Socket::syserror(), WSAGetLastError()); -#else - throw SocketError("poll", Socket::syserror(), errno); -#endif + throw SocketError(SocketError::System, "poll"); } std::vector<SocketStatus> sockets;
--- a/C++/SocketTcp.cpp Tue Mar 03 18:48:54 2015 +0100 +++ b/C++/SocketTcp.cpp Wed Mar 04 13:45:56 2015 +0100 @@ -27,7 +27,7 @@ void SocketAbstractTcp::listen(int max) { if (::listen(m_handle, max) == Error) - throw SocketError("listen", Socket::syserror(), errno); + throw SocketError(SocketError::System, "listen"); } /* -------------------------------------------------------- @@ -54,15 +54,17 @@ if (handle == Invalid) { #if defined(_WIN32) - if (WSAGetLastError() == WSAEWOULDBLOCK) - throw SocketError("accept", Socket::syserror(WSAEWOULDBLOCK), WSAEWOULDBLOCK /* TODO: Read */); + int error = WSAGetLastError(); - throw SocketError("accept", Socket::syserror(), WSAGetLastError()); + if (error == WSAEWOULDBLOCK) + throw SocketError(SocketError::WouldBlockRead, "accept", error); + + throw SocketError(SocketError::System, "accept", error); #else if (errno == EAGAIN || errno == EWOULDBLOCK) - throw SocketError("accept", Socket::syserror(EWOULDBLOCK), EWOULDBLOCK /* TODO: Read */); + throw SocketError(SocketError::WouldBlockRead, "accept"); - throw SocketError("accept", Socket::syserror(), errno); + throw SocketError(SocketError::System, "accept"); #endif } @@ -86,15 +88,17 @@ * accomplished yet. */ #if defined(_WIN32) - if (WSAGetLastError() == WSAEWOULDBLOCK) - throw SocketError("connect", Socket::syserror(WSAEWOULDBLOCK), WSAEWOULDBLOCK /*, Write */); + int error = WSAGetLastError(); - throw SocketError("connect", Socket::syserror(WSAEWOULDBLOCK), WSAGetLastError()); + if (error == WSAEWOULDBLOCK) + throw SocketError(SocketError::WouldBlockWrite, "connect", error); + + throw SocketError(SocketError::System, "connect", error); #else if (errno == EINPROGRESS) - throw SocketError("connect", Socket::syserror(EINPROGRESS), EINPROGRESS /*, Write */); + throw SocketError(SocketError::WouldBlockWrite, "connect"); - throw SocketError("connect", Socket::syserror(), errno); + throw SocketError(SocketError::System, "connect"); #endif } @@ -120,7 +124,7 @@ int error = get<int>(SOL_SOCKET, SO_ERROR); if (error) { - throw SocketError("connect", Socket::syserror(error), error); + throw SocketError(SocketError::System, "connect", error); } } @@ -150,15 +154,17 @@ nbread = ::recv(m_handle, (Socket::Arg)data, dataLen, 0); if (nbread == Error) { #if defined(_WIN32) - if (WSAGetLastError() == WSAEWOULDBLOCK) - throw SocketError("recv", Socket::syserror(), WSAEWOULDBLOCK /* TODO: Read */); + int error = WSAGetLastError(); - throw SocketError("recv", Socket::syserror(), WSAGetLastError()); + if (error == WSAEWOULDBLOCK) + throw SocketError(SocketError::WouldBlockRead, "recv", error) + + throw SocketError(SocketError::System, "recv", error); #else if (errno == EAGAIN || errno == EWOULDBLOCK) - throw SocketError("recv", Socket::syserror(), errno /* TODO: Read */); + throw SocketError(SocketError::WouldBlockRead, "recv"); - throw SocketError("recv", Socket::syserror(), errno); + throw SocketError(SocketError::System, "recv"); #endif } else if (nbread == 0) m_state = SocketState::Closed; @@ -182,15 +188,17 @@ nbsent = ::send(m_handle, (Socket::ConstArg)data, length, 0); if (nbsent == Error) { #if defined(_WIN32) - if (WSAGetLastError() == WSAEWOULDBLOCK) - throw SocketError("send", Socket::syserror(), WSAEWOULDBLOCK /* Write */); + int error = WSAGetLastError(); - throw SocketError("send", Socket::syserror(), WSAGetLastError()); + if (error == WSAEWOULDBLOCK) + throw SocketError(SocketError::WouldBlockWrite, "send", error); + + throw SocketError(SocketError::System, "send", error); #else if (errno == EAGAIN || errno == EWOULDBLOCK) - throw SocketError("send", Socket::syserror(), errno /*, Write */); + throw SocketError(SocketError::WouldBlockWrite, "send"); - throw SocketError("send", Socket::syserror(), errno); + throw SocketError(SocketError::System, "send"); #endif }
--- a/C++/SocketUdp.cpp Tue Mar 03 18:48:54 2015 +0100 +++ b/C++/SocketUdp.cpp Wed Mar 04 13:45:56 2015 +0100 @@ -39,15 +39,17 @@ if (nbread == Error) { #if defined(_WIN32) - if (WSAGetLastError() == WSAEWOULDBLOCK) - throw SocketError("recvfrom", Socket::syserror(), WSAEWOULDBLOCK /*, Read */); + int error = WSAGetLastError(); - throw SocketError("recvfrom", Socket::syserror(), WSAGetLastError()); + if (error == WSAEWOULDBLOCK) + throw SocketError(SocketError::WouldBlockRead, "recvfrom", error); + + throw SocketError(SocketError::System, "recvfrom", error); #else if (errno == EAGAIN || errno == EWOULDBLOCK) - throw SocketError("recvfrom", Socket::syserror(), errno /* , Read */); + throw SocketError(SocketError::WouldBlockRead, "recvfrom"); - throw SocketError("recvfrom", Socket::syserror(), errno); + throw SocketError(SocketError::System, "recvfrom"); #endif } @@ -61,15 +63,17 @@ nbsent = ::sendto(m_handle, (Socket::ConstArg)data, length, 0, (const sockaddr *)&info.address(), info.length()); if (nbsent == Error) { #if defined(_WIN32) - if (WSAGetLastError() == WSAEWOULDBLOCK) - throw SocketError("sendto", Socket::syserror(), WSAEWOULDBLOCK /*, Write */); + int error = WSAGetLastError(); - throw SocketError("sendto", Socket::syserror(), errno); + if (error == WSAEWOULDBLOCK) + throw SocketError(SocketError::WouldBlockWrite, "sendto", error); + + throw SocketError(SocketError::System, "sendto", error); #else if (errno == EAGAIN || errno == EWOULDBLOCK) - throw SocketError("sendto", Socket::syserror(), errno /*, Write */); + throw SocketError(SocketError::WouldBlockWrite, "sendto"); - throw SocketError("sendto", Socket::syserror(), errno); + throw SocketError(SocketError::System, "sendto"); #endif }