Mercurial > code
changeset 459:819bccefce8e
Socket:
- Two new states: ConnectingRead | ConnectingWrite,
- The connect() functions does not throw anymore if the operation is in
progress for simpler implementations.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 03 Nov 2015 17:48:35 +0100 |
parents | db738947f359 |
children | f6b4c7491d18 |
files | C++/examples/Socket/non-blocking-connect.cpp C++/modules/Socket/Sockets.h |
diffstat | 2 files changed, 36 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/examples/Socket/non-blocking-connect.cpp Tue Nov 03 16:38:48 2015 +0100 +++ b/C++/examples/Socket/non-blocking-connect.cpp Tue Nov 03 17:48:35 2015 +0100 @@ -38,37 +38,30 @@ socket.setBlockMode(false); - while (socket.state() != net::State::Connected && timer.elapsed() < (WITH_TIMEOUT * 1000)) { - try { - /* - * If the socket is in state Open then no connection has been attempted, otherwise if it's Connecting, - * then we can just resume the connection process. - */ - if (socket.state() == net::State::Open) { - std::cout << "Trying to connect to " << WITH_HOST << ":" << WITH_PORT << std::endl; - socket.connect(net::Ipv4{WITH_HOST, WITH_PORT}); - } else { - socket.connect(); - } - } catch (const net::Error &error) { + try { + std::cout << "Trying to connect to " << WITH_HOST << ":" << WITH_PORT << std::endl; + socket.connect(net::Ipv4{WITH_HOST, WITH_PORT}); + + while (socket.state() != net::State::Connected) { listener.remove(socket.handle()); - if (error.code() == net::Error::WouldBlockRead) { + if (socket.state() == net::State::ConnectingRead) { listener.set(socket.handle(), net::FlagRead); - } else if (error.code() == net::Error::WouldBlockWrite) { + } else if (socket.state() == net::State::ConnectingWrite) { listener.set(socket.handle(), net::FlagWrite); - } else { - std::cerr << "error: " << error.what() << std::endl; - std::exit(1); } - try { - listener.wait(std::chrono::seconds(WITH_TIMEOUT)); - } catch (...) { - std::cerr << "timeout while connecting" << std::endl; - std::exit(1); - } + listener.wait(std::chrono::seconds(WITH_TIMEOUT)); + socket.connect(); } + } catch (const net::Error &error) { + if (error.code() == net::Error::Timeout) { + std::cerr << "timeout while connecting" << std::endl; + } else { + std::cerr << "error: " << error.what() << std::endl; + } + + std::exit(1); } std::cout << "Successfully connected!" << std::endl;
--- a/C++/modules/Socket/Sockets.h Tue Nov 03 16:38:48 2015 +0100 +++ b/C++/modules/Socket/Sockets.h Tue Nov 03 17:48:35 2015 +0100 @@ -399,13 +399,14 @@ * @brief Current socket state */ enum class State { - Open, //!< Socket is open - Bound, //!< Socket is bound to an address - Connecting, //!< Connection is in progress - Connected, //!< Connection is complete - Accepting, //!< The socket is being accepted (client) - Accepted, //!< Socket has been accepted (client) - Closed, //!< The socket has been closed + Open, //!< Socket is open + Bound, //!< Socket is bound to an address + ConnectingRead, //!< Connection is in progress but requires to bereadable + ConnectingWrite, //!< Connection is in progress and requires to be writable + Connected, //!< Connection is complete + Accepting, //!< The socket is being accepted (client) + Accepted, //!< Socket has been accepted (client) + Closed, //!< The socket has been closed }; /* }}} */ @@ -675,9 +676,9 @@ /** * Connect to the connection to the specified address. If the socket is marked non-blocking and the - * connection cannot be established, an error is thrown with WouldBlockWrite or WouldBlockRead as the code. The - * user is then responsible to wait that the socket is writable or readable using a listener and then call the - * overloaded connect() function which takes 0 argument. + * connection cannot be established, the state is set to ConnectingRead or ConnectingWrite depending + * on the underlying implementation. The user is then responsible to wait that the socket is writable + * or readable using a listener and then call the overloaded connect() function which takes 0 argument. * * @param address the address * @param length the address length @@ -707,12 +708,12 @@ * Continue the connection, only required with non-blocking sockets. Just like the initial connect() call, * this function can still be in progress. * - * @pre state() must be State::Connecting + * @pre state() must be State::ConnectingRead or State::ConnectingWrite * @throw Error on errors */ inline void connect() { - assert(m_state == State::Connecting); + assert(m_state == State::ConnectingRead || m_state == State::ConnectingWrite); m_type.connect(*this); } @@ -1339,18 +1340,16 @@ int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { - sc.setState(State::Connecting); - throw Error{Error::WouldBlockWrite, "connect", error}; + sc.setState(State::ConnectingWrite); + } else { + throw Error{Error::System, "connect", error}; } - - throw Error{Error::System, "connect", error}; #else if (errno == EINPROGRESS) { - sc.setState(State::Connecting); - throw Error{Error::WouldBlockWrite, "connect"}; + sc.setState(State::ConnectingWrite); + } else { + throw Error{Error::System, "connect"}; } - - throw Error{Error::System, "connect"}; #endif } else { sc.setState(State::Connected);