diff --git a/Test/Sample.AsyncSocket.h b/Test/Sample.AsyncSocket.h index 7006f01..09833cb 100644 --- a/Test/Sample.AsyncSocket.h +++ b/Test/Sample.AsyncSocket.h @@ -38,7 +38,7 @@ void example_binding(const vu::Endpoint& endpoint) server.bind(endpoint); server.listen(); server.run(); - server.close(); + // server.stop(); } void example_inheritance(const vu::Endpoint& endpoint) @@ -77,7 +77,7 @@ void example_inheritance(const vu::Endpoint& endpoint) server.bind(endpoint); server.listen(); server.run(); - server.close(); + // server.stop(); } #endif // VU_INET_ENABLED diff --git a/include/Vutils.h b/include/Vutils.h index 150e5d7..8f144b6 100644 --- a/include/Vutils.h +++ b/include/Vutils.h @@ -109,6 +109,7 @@ #include #include #include +#include #include #include #include @@ -1295,7 +1296,6 @@ class Socket : public LastError const address_family_t af = AF_INET, const type_t type = SOCK_STREAM, const protocol_t proto = IPPROTO_IP, - const bool wsa = true, const Options* options = nullptr ); Socket(const Socket& right); @@ -1306,7 +1306,6 @@ class Socket : public LastError const Socket& operator=(const Socket& right); const SOCKET& vuapi handle() const; - const WSADATA& vuapi wsa_data() const; const address_family_t vuapi af() const; const type_t vuapi type() const; const protocol_t vuapi protocol() const; @@ -1342,9 +1341,9 @@ class Socket : public LastError IResult vuapi close(); - const sockaddr_in vuapi get_local_sai() const; - const sockaddr_in vuapi get_remote_sai() const; - std::string vuapi get_host_name() const; + const sockaddr_in vuapi get_local_sai(); + const sockaddr_in vuapi get_remote_sai(); + std::string vuapi get_host_name(); Options& options(); @@ -1358,7 +1357,6 @@ class Socket : public LastError std::string vuapi get_host_address(const std::string& name) const; private: - bool m_wsa; type_t m_type; WSADATA m_wsa_data; address_family_t m_af; @@ -1366,7 +1364,7 @@ class Socket : public LastError sockaddr_in m_sai; SOCKET m_socket; Options m_options; - bool m_self; + bool m_attached; }; class AsyncSocket : public LastError @@ -1424,9 +1422,7 @@ class AsyncSocket : public LastError VUResult vuapi listen(const int maxcon = SOMAXCONN); VUResult vuapi run(const bool in_worker_thread = false); - - VUResult vuapi stop(); - IResult vuapi close(const Socket::shutdowns_t flags = SD_BOTH, const bool cleanup = false); + VUResult vuapi stop(const Socket::shutdowns_t flags = SD_BOTH, const bool cleanup = false); void vuapi get_connections(std::set& connections); VUResult vuapi disconnect_connections(const Socket::shutdowns_t flags = SD_BOTH, const bool cleanup = false); @@ -1454,16 +1450,18 @@ class AsyncSocket : public LastError IResult vuapi do_close(WSANETWORKEVENTS& events, SOCKET& connection); protected: + HANDLE m_thread; + std::atomic m_running; + + side_type m_side; vu::Socket m_socket; - side_type m_side; - bool m_running; - DWORD m_n_events; + + DWORD m_n_events; SOCKET m_connections[WSA_MAXIMUM_WAIT_EVENTS]; - std::recursive_mutex m_mutex_client_list; WSAEVENT m_events[WSA_MAXIMUM_WAIT_EVENTS]; + std::recursive_mutex m_mutex_client_list; + fn_prototype_t m_functions[function::UNDEFINED]; - std::mutex m_mutex; - HANDLE m_thread; }; #endif // VU_INET_ENABLED diff --git a/src/details/asyncsocket.cpp b/src/details/asyncsocket.cpp index 5adbef1..d6b2afd 100644 --- a/src/details/asyncsocket.cpp +++ b/src/details/asyncsocket.cpp @@ -19,7 +19,7 @@ AsyncSocket::AsyncSocket( const vu::Socket::type_t type, const vu::Socket::protocol_t proto, const vu::Socket::Options* options -) : m_socket(af, type, proto, true, options), m_thread(INVALID_HANDLE_VALUE), LastError() +) : m_socket(af, type, proto, options), m_thread(INVALID_HANDLE_VALUE), LastError() { UNREFERENCED_PARAMETER(m_side); @@ -33,15 +33,12 @@ AsyncSocket::AsyncSocket( AsyncSocket::~AsyncSocket() { - this->close(); } void vuapi AsyncSocket::initialze() { m_n_events = 0; - std::lock_guard lg(m_mutex_client_list); - memset(m_connections, int(INVALID_SOCKET), sizeof(m_connections)); memset(m_events, int(0), sizeof(m_events)); @@ -97,8 +94,6 @@ VUResult vuapi AsyncSocket::listen(const int maxcon) return 2; } - std::lock_guard lg(m_mutex_client_list); - m_connections[m_n_events] = m_socket.handle(); m_events[m_n_events] = event; m_n_events++; @@ -110,9 +105,14 @@ VUResult vuapi AsyncSocket::listen(const int maxcon) return result; } -IResult vuapi AsyncSocket::close(const Socket::shutdowns_t flags, const bool cleanup) +IResult vuapi AsyncSocket::stop(const Socket::shutdowns_t flags, const bool cleanup) { - this->stop(); + if (!m_socket.available()) + { + return 1; + } + + m_running = false; this->disconnect_connections(flags, cleanup); @@ -121,18 +121,6 @@ IResult vuapi AsyncSocket::close(const Socket::shutdowns_t flags, const bool cle TerminateThread(m_thread, 0); // CloseHandle(m_thread); } - auto result = m_socket.close(); - - m_last_error_code = GetLastError(); - - return result; -} - -VUResult vuapi AsyncSocket::stop() -{ - m_mutex.lock(); - m_running = false; - m_mutex.unlock(); return VU_OK; } @@ -152,8 +140,6 @@ VUResult vuapi AsyncSocket::connect(const Endpoint& endpoint) return 2; } - std::lock_guard lg(m_mutex_client_list); - auto result = m_socket.connect(endpoint); if (result == VU_OK) { @@ -179,31 +165,29 @@ void vuapi AsyncSocket::get_connections(std::set& connections) { connections.clear(); - if (m_socket.available()) + if (!m_socket.available()) { - std::lock_guard lg(m_mutex_client_list); + return; + } - for (auto& socket : m_connections) + for (auto& socket : m_connections) + { + if (socket == INVALID_SOCKET) // ignore invalid socket handle { - if (socket == INVALID_SOCKET) // ignore invalid socket handle - { - continue; - } - - if (m_side == side_type::SERVER && socket == m_socket.handle()) // ignore server socket handle - { - continue; - } + continue; + } - connections.insert(socket); + if (m_side == side_type::SERVER && socket == m_socket.handle()) // ignore server socket handle + { + continue; } + + connections.insert(socket); } } VUResult vuapi AsyncSocket::disconnect_connections(const Socket::shutdowns_t flags, const bool cleanup) { - std::lock_guard lg(m_mutex_client_list); - std::set connections; this->get_connections(connections); for (const auto& connection : connections) @@ -365,8 +349,6 @@ IResult vuapi AsyncSocket::do_open(WSANETWORKEVENTS& events, SOCKET& connection) return events.iErrorCode[FD_ACCEPT_BIT]; } - std::lock_guard lg(m_mutex_client_list); - Socket::Handle obj = { 0 }; int n = static_cast(sizeof(obj.sai)); @@ -398,8 +380,6 @@ IResult vuapi AsyncSocket::do_recv(WSANETWORKEVENTS& events, SOCKET& connection) return events.iErrorCode[FD_READ_BIT]; } - std::lock_guard lg(m_mutex_client_list); - Socket socket(m_socket); socket.attach(connection); this->on_recv(socket); @@ -415,8 +395,6 @@ IResult vuapi AsyncSocket::do_send(WSANETWORKEVENTS& events, SOCKET& connection) return events.iErrorCode[FD_WRITE_BIT]; } - std::lock_guard lg(m_mutex_client_list); - Socket socket(m_socket); socket.attach(connection); this->on_send(socket); @@ -427,7 +405,7 @@ IResult vuapi AsyncSocket::do_send(WSANETWORKEVENTS& events, SOCKET& connection) IResult vuapi AsyncSocket::do_close(WSANETWORKEVENTS& events, SOCKET& connection) { - // TODO: In certain cases(e.g., user - mode drivers), it crashes. + // TODO: Vic. In certain cases(e.g., user - mode drivers), it crashes. // I'm not sure why, so temporarily comment out these codes. // // if (events.iErrorCode[FD_CLOSE_BIT] != 0) @@ -435,8 +413,6 @@ IResult vuapi AsyncSocket::do_close(WSANETWORKEVENTS& events, SOCKET& connection // return events.iErrorCode[FD_CLOSE_BIT]; // } - std::lock_guard lg(m_mutex_client_list); - std::vector> in_used_connections; for (int i = 0; i < WSA_MAXIMUM_WAIT_EVENTS; i++) diff --git a/src/details/socket.cpp b/src/details/socket.cpp index 2289e2f..8b196e7 100644 --- a/src/details/socket.cpp +++ b/src/details/socket.cpp @@ -103,29 +103,30 @@ Socket::Socket( const address_family_t af, const type_t type, const protocol_t proto, - const bool wsa, const Options* options -) : LastError(), m_af(af), m_type(type), m_proto(proto), m_wsa(wsa), m_self(false) +) : LastError(), m_af(af), m_type(type), m_proto(proto), m_attached(false) { ZeroMemory(&m_wsa_data, sizeof(m_wsa_data)); - ZeroMemory(&m_sai, sizeof(m_sai)); + if (WSAStartup(MAKEWORD(2, 2), &m_wsa_data) == INVALID_SOCKET) + { + m_last_error_code = GetLastError(); + assert("start wsa failed."); + } if (options != nullptr) { m_options = *options; } - if (m_wsa) - { - if (WSAStartup(MAKEWORD(2, 2), &m_wsa_data) != 0) - { - m_last_error_code = GetLastError(); - } - } + ZeroMemory(&m_sai, sizeof(m_sai)); + m_sai.sin_family = m_af; m_socket = ::socket(m_af, m_type, m_proto); - - m_sai.sin_family = m_af; + if (m_socket == INVALID_SOCKET) + { + m_last_error_code = GetLastError(); + assert("open socket failed."); + } } Socket::Socket(const Socket& right) @@ -135,14 +136,23 @@ Socket::Socket(const Socket& right) Socket::~Socket() { - this->close(); + if (m_attached) + { + return; // ignore if the connection is attached from outside + } - if (m_wsa) + if (::closesocket(m_socket) == INVALID_SOCKET) { - WSACleanup(); + assert("close socket failed."); + m_last_error_code = GetLastError(); + m_socket = INVALID_SOCKET; } - m_last_error_code = GetLastError(); + if (WSACleanup() == INVALID_SOCKET) + { + assert("clean wsa failed."); + m_last_error_code = GetLastError(); + } } bool Socket::operator==(const Socket& right) @@ -162,17 +172,13 @@ const vu::Socket& Socket::operator=(const Socket& right) return *this; } - m_wsa = false; - // m_wsa = right.m_wsa; - // m_wsa_data = right.m_wsa_data; - m_type = right.m_type; m_af = right.m_af; m_proto = right.m_proto; m_sai = right.m_sai; m_socket = right.m_socket; m_options = right.m_options; - m_self = right.m_self; + m_attached = right.m_attached; return *this; } @@ -198,6 +204,7 @@ void vuapi Socket::attach(const Handle& socket) { m_socket = socket.s; m_sai = socket.sai; + m_attached = true; } void vuapi Socket::detach() @@ -211,11 +218,6 @@ Socket::Options& Socket::options() return m_options; } -const WSADATA& vuapi Socket::wsa_data() const -{ - return m_wsa_data; -} - const Socket::address_family_t vuapi Socket::af() const { return m_af; @@ -236,7 +238,7 @@ const SOCKET& vuapi Socket::handle() const return m_socket; } -const sockaddr_in vuapi Socket::get_local_sai() const +const sockaddr_in vuapi Socket::get_local_sai() { sockaddr_in result = { 0 }; @@ -244,12 +246,13 @@ const sockaddr_in vuapi Socket::get_local_sai() const { auto size = int(sizeof(result)); ::getsockname(m_socket, (struct sockaddr*)&result, &size); + m_last_error_code = GetLastError(); } return result; } -const sockaddr_in vuapi Socket::get_remote_sai() const +const sockaddr_in vuapi Socket::get_remote_sai() { sockaddr_in result = { 0 }; @@ -257,6 +260,7 @@ const sockaddr_in vuapi Socket::get_remote_sai() const { auto size = int(sizeof(result)); ::getpeername(m_socket, (struct sockaddr*)&result, &size); + m_last_error_code = GetLastError(); } return result; @@ -273,7 +277,7 @@ VUResult vuapi Socket::set_option( return 1; } - if (::setsockopt(m_socket, level, option, static_cast(value), size) != 0) + if (::setsockopt(m_socket, level, option, static_cast(value), size) == INVALID_SOCKET) { m_last_error_code = GetLastError(); return 3; @@ -292,6 +296,7 @@ VUResult vuapi Socket::enable_non_blocking(bool state) ulong non_block = state ? 1 : 0; if (::ioctlsocket(m_socket, FIONBIO, &non_block) == SOCKET_ERROR) { + m_last_error_code = GetLastError(); return 2; } @@ -394,8 +399,6 @@ VUResult vuapi Socket::connect(const Endpoint& endpoint) return m_last_error_code == WSAEWOULDBLOCK ? VU_OK : 2; } - m_self = true; - return VU_OK; } @@ -620,10 +623,7 @@ VUResult vuapi Socket::close() return 1; } - if (m_self) - { - ::closesocket(m_socket); - } + ::closesocket(m_socket); m_socket = INVALID_SOCKET; @@ -649,16 +649,18 @@ VUResult vuapi Socket::disconnect(const shutdowns_t flags, const bool cleanup) return 2; } - if (closesocket(m_socket) == SOCKET_ERROR) + if (::closesocket(m_socket) == SOCKET_ERROR) { m_last_error_code = GetLastError(); return 3; } + m_socket = INVALID_SOCKET; + return VU_OK; } -std::string vuapi Socket::get_host_name() const +std::string vuapi Socket::get_host_name() { std::string result = ""; @@ -676,7 +678,7 @@ std::string vuapi Socket::get_host_name() const ZeroMemory(h.get(), MAXBYTE); if (::gethostname(h.get(), MAXBYTE) == SOCKET_ERROR) { - //m_last_error_code = GetLastError(); + m_last_error_code = GetLastError(); return result; }