diff --git a/net/include/ftl/net/handlers.hpp b/net/include/ftl/net/handlers.hpp index f3904da8b1ff4533b967f08bc2f2ddfe83cb6d20..9a515db88a6d776075bca2858380c6e73a04a0e9 100644 --- a/net/include/ftl/net/handlers.hpp +++ b/net/include/ftl/net/handlers.hpp @@ -6,6 +6,8 @@ namespace ftl { namespace net { +class Socket; + typedef std::function<void(int, std::string&)> sockdatahandler_t; typedef std::function<void(int)> sockerrorhandler_t; typedef std::function<void()> sockconnecthandler_t; diff --git a/net/include/ftl/net/listener.hpp b/net/include/ftl/net/listener.hpp index ca3b2c5d151aa871358d5929f979c82a5e63b27d..97171b5f1bf3ff9ff7ab4954ec2483f9e495ee05 100644 --- a/net/include/ftl/net/listener.hpp +++ b/net/include/ftl/net/listener.hpp @@ -10,6 +10,10 @@ #include <winsock.h> #endif +#include <ftl/net/handlers.hpp> + +#include <vector> + namespace ftl { namespace net { @@ -23,9 +27,13 @@ class Listener { void close(); int _socket() { return descriptor_; } + void connection(Socket &s); + void onConnection(connecthandler_t h) { handler_connect_.push_back(h); }; + private: int descriptor_; sockaddr_in slocalAddr; + std::vector<connecthandler_t> handler_connect_; }; }; diff --git a/net/src/listener.cpp b/net/src/listener.cpp index f3a92d8a74ee74922d1da44d79cf417be6670c76..4b9e8d1ef8d31875ef42da4b8426d35b5ae09c51 100644 --- a/net/src/listener.cpp +++ b/net/src/listener.cpp @@ -97,8 +97,12 @@ Listener::~Listener() { close(); } +void Listener::connection(Socket &s) { + for (auto h : handler_connect_) h(s); +} + void Listener::close() { - //if (isConnected()) { + if (isListening()) { #ifndef WIN32 ::close(descriptor_); #else @@ -107,6 +111,6 @@ void Listener::close() { descriptor_ = INVALID_SOCKET; // Attempt auto reconnect? - //} + } } diff --git a/net/src/net.cpp b/net/src/net.cpp index 23eaeae68ef5311ad3a1e71d750c2b6e1a21b7c7..ad56f07b8a9e044972f3095574c7908ec199f827 100644 --- a/net/src/net.cpp +++ b/net/src/net.cpp @@ -14,7 +14,7 @@ static std::vector<shared_ptr<ftl::net::Listener>> listeners; static fd_set sfdread; static fd_set sfderror; -static int freeSocket() { +/*static int freeSocket() { int freeclient = -1; //Find a free client slot and allocated it @@ -37,7 +37,7 @@ static int freeSocket() { } return freeclient; -} +}*/ static int setDescriptors() { //Reset all file descriptors @@ -79,30 +79,17 @@ shared_ptr<Listener> ftl::net::listen(const char *uri) { shared_ptr<Socket> ftl::net::connect(const char *uri) { shared_ptr<Socket> s(new Socket(uri)); - int fs = freeSocket(); - if (fs >= 0) { - sockets[fs] = s; - return s; - } else { - return NULL; - } + sockets.push_back(s); + return s; } void ftl::net::stop() { for (auto s : sockets) { - if (s != NULL) s->close(); + s->close(); } sockets.clear(); - /*#ifndef WIN32 - if (ssock != INVALID_SOCKET) close(ssock); - #else - if (ssock != INVALID_SOCKET) closesocket(ssock); - #endif - - ssock = INVALID_SOCKET;*/ - for (auto l : listeners) { l->close(); } @@ -157,6 +144,9 @@ bool _run(bool blocking, bool nodelay) { sockets.push_back(sock); + // Call connection handlers + l->connection(*sock); + // TODO Save the ip address // deal with both IPv4 and IPv6: /*if (addr.ss_family == AF_INET) { diff --git a/net/src/socket.cpp b/net/src/socket.cpp index c2d81c172859a7361d24fe68ecb56363f583ceb0..b81c7151c47319081f2c7e9c233ec84d83d1ae40 100644 --- a/net/src/socket.cpp +++ b/net/src/socket.cpp @@ -108,6 +108,7 @@ static int wsConnect(URI &uri) { Socket::Socket(int s) : m_sock(s), m_pos(0) { // TODO Get the remote address. m_valid = true; + m_buffer = new char[BUFFER_SIZE]; } Socket::Socket(const char *pUri) : m_uri(pUri), m_pos(0) { @@ -209,6 +210,7 @@ Socket::~Socket() { close(); // Delete socket buffer - delete [] m_buffer; + if (m_buffer) delete [] m_buffer; + m_buffer = NULL; } diff --git a/net/test/net_raw.cpp b/net/test/net_raw.cpp index e5b443cff1990063e3f8a468fce1e3c793300ae4..59a849064e3ae3a200c090bc5c65703701bb216a 100644 --- a/net/test/net_raw.cpp +++ b/net/test/net_raw.cpp @@ -253,6 +253,25 @@ TEST_CASE("net::listen()", "[net]") { ftl::net::stop(); } + + SECTION("on connection event") { + auto l = ftl::net::listen("tcp://*:7078"); + REQUIRE( l->isListening() ); + + bool connected = false; + + l->onConnection([&](Socket &s) { + REQUIRE( s.isConnected() ); + connected = true; + }); + + auto sock = ftl::net::connect("tcp://127.0.0.1:7078"); + ftl::net::wait(); + REQUIRE( connected ); + std::cout << "PRE STOP" << std::endl; + ftl::net::stop(); + std::cout << "POST STOP" << std::endl; + } } TEST_CASE("Socket.onMessage()", "[net]") {