From a9b8a530b1e082d2ab108947ef28e0a58c8fd838 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 9 Jan 2015 14:07:59 +0000 Subject: Extracted Google connection test --- tests/CMakeLists.txt | 1 + tests/Network/CMakeLists.txt | 14 ++++++++ tests/Network/Google.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 tests/Network/CMakeLists.txt create mode 100644 tests/Network/Google.cpp (limited to 'tests') diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1fbd88f04..265640cc8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,3 +5,4 @@ enable_testing() include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(ChunkData) +add_subdirectory(Network) diff --git a/tests/Network/CMakeLists.txt b/tests/Network/CMakeLists.txt new file mode 100644 index 000000000..8aae84590 --- /dev/null +++ b/tests/Network/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required (VERSION 2.6) + +enable_testing() + +include_directories(${CMAKE_SOURCE_DIR}/src/) +include_directories(${CMAKE_SOURCE_DIR}/lib/libevent/include) + +add_definitions(-DTEST_GLOBALS=1) +add_library(Network ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp) +target_link_libraries(Network event_core event_extra) + +add_executable(Google-exe Google.cpp) +target_link_libraries(Google-exe Network) +add_test(NAME Google-test COMMAND Google-exe) diff --git a/tests/Network/Google.cpp b/tests/Network/Google.cpp new file mode 100644 index 000000000..0aa52d025 --- /dev/null +++ b/tests/Network/Google.cpp @@ -0,0 +1,85 @@ + +#include "Globals.h" + +#include +#include "OSSupport/Event.h" + +#include "OSSupport/Network.h" + +/** Connect callbacks that send a HTTP GET request for google.com when connected. */ +class cHTTPConnectCallbacks: + public cNetwork::cConnectCallbacks +{ + cEvent & m_Event; + virtual void OnSuccess(cTCPLink & a_Link) override + { + LOGD("Connected, sending HTTP GET"); + if (!a_Link.Send("GET / HTTP/1.0\r\nHost:google.com\r\n\r\n")) + { + LOGWARNING("Sending HTTP GET failed"); + } + LOGD("HTTP GET queued."); + } + + virtual void OnError(int a_ErrorCode) override + { + LOGD("Error while connecting HTTP: %d", a_ErrorCode); + m_Event.Set(); + } + +public: + cHTTPConnectCallbacks(cEvent & a_Event): + m_Event(a_Event) + { + } +}; + + +/** cTCPLink callbacks that dump everything it received to the log. */ +class cDumpCallbacks: + public cTCPLink::cCallbacks +{ + cEvent & m_Event; + + virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Size) override + { + // Log the incoming data size: + AString Hex; + CreateHexDump(Hex, a_Data, a_Size, 16); + LOGD("Incoming data: %u bytes:\n%s", static_cast(a_Size), Hex.c_str()); + } + + virtual void OnRemoteClosed(cTCPLink & a_Link) override + { + LOGD("Remote has closed the connection."); + m_Event.Set(); + } + + virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) override + { + LOGD("Error in the cDumpCallbacks."); + m_Event.Set(); + } + +public: + cDumpCallbacks(cEvent & a_Event): + m_Event(a_Event) + { + } +}; + + +int main() { + cEvent evtFinish; + + LOGD("Network test: Connecting to google.com:80, reading front page via HTTP."); + if (!cNetwork::Connect("google.com", 80, std::make_shared(evtFinish), std::make_shared(evtFinish))) + { + LOGWARNING("Cannot queue connection to google.com"); + abort(); + } + LOGD("Connect request has been queued."); + + evtFinish.Wait(); + LOGD("Network test finished"); +} -- cgit v1.2.3 From fde44cba0815f626253c0d352cd0d782eec94328 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 11 Jan 2015 11:21:18 +0100 Subject: cNetwork: Implemented HostnameToIP lookups. --- tests/Network/CMakeLists.txt | 9 ++++++ tests/Network/EchoServer.cpp | 19 +++++++++++++ tests/Network/Google.cpp | 23 +++++++++++++-- tests/Network/NameLookup.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 tests/Network/EchoServer.cpp create mode 100644 tests/Network/NameLookup.cpp (limited to 'tests') diff --git a/tests/Network/CMakeLists.txt b/tests/Network/CMakeLists.txt index 8aae84590..a63ce7dfe 100644 --- a/tests/Network/CMakeLists.txt +++ b/tests/Network/CMakeLists.txt @@ -8,7 +8,16 @@ include_directories(${CMAKE_SOURCE_DIR}/lib/libevent/include) add_definitions(-DTEST_GLOBALS=1) add_library(Network ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp) target_link_libraries(Network event_core event_extra) +if (MSVC) + target_link_libraries(Network ws2_32.lib) +endif() add_executable(Google-exe Google.cpp) target_link_libraries(Google-exe Network) add_test(NAME Google-test COMMAND Google-exe) + +add_executable(EchoServer EchoServer.cpp) +target_link_libraries(EchoServer Network) + +add_executable(NameLookup NameLookup.cpp) +target_link_libraries(NameLookup Network) diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp new file mode 100644 index 000000000..def064083 --- /dev/null +++ b/tests/Network/EchoServer.cpp @@ -0,0 +1,19 @@ + +// EchoServer.cpp + +// Implements an Echo server using the LibEvent-based cNetwork API, as a test of that API + + + + + + +int main() +{ + // TODO + return 0; +} + + + + diff --git a/tests/Network/Google.cpp b/tests/Network/Google.cpp index 0aa52d025..de5f95e1f 100644 --- a/tests/Network/Google.cpp +++ b/tests/Network/Google.cpp @@ -1,11 +1,17 @@ -#include "Globals.h" +// Google.cpp + +// Implements a HTTP download of the google's front page using the LibEvent-based cNetwork API +#include "Globals.h" #include #include "OSSupport/Event.h" - #include "OSSupport/Network.h" + + + + /** Connect callbacks that send a HTTP GET request for google.com when connected. */ class cHTTPConnectCallbacks: public cNetwork::cConnectCallbacks @@ -35,6 +41,9 @@ public: }; + + + /** cTCPLink callbacks that dump everything it received to the log. */ class cDumpCallbacks: public cTCPLink::cCallbacks @@ -69,7 +78,11 @@ public: }; -int main() { + + + +int main() +{ cEvent evtFinish; LOGD("Network test: Connecting to google.com:80, reading front page via HTTP."); @@ -83,3 +96,7 @@ int main() { evtFinish.Wait(); LOGD("Network test finished"); } + + + + diff --git a/tests/Network/NameLookup.cpp b/tests/Network/NameLookup.cpp new file mode 100644 index 000000000..daa72a3cb --- /dev/null +++ b/tests/Network/NameLookup.cpp @@ -0,0 +1,67 @@ + +// NameLookup.cpp + +// Implements a DNS name lookup using the LibEvent-based cNetwork API + +#include "Globals.h" +#include +#include "OSSupport/Event.h" +#include "OSSupport/Network.h" + + + + + +class cFinishLookupCallbacks: + public cNetwork::cResolveNameCallbacks +{ + cEvent & m_Event; + + virtual void OnNameResolved(const AString & a_Name, const AString & a_IP) override + { + LOGD("%s resolves to IP %s", a_Name.c_str(), a_IP.c_str()); + } + + virtual void OnError(int a_ErrorCode) override + { + LOGD("Error %d while performing lookup!", a_ErrorCode); + abort(); + } + + virtual void OnFinished(void) override + { + LOGD("Resolving finished."); + m_Event.Set(); + } + +public: + cFinishLookupCallbacks(cEvent & a_Event): + m_Event(a_Event) + { + } +}; + + + + + +int main() +{ + cEvent evtFinish; + + LOGD("Network test: Looking up google.com"); + if (!cNetwork::HostnameToIP("google.com", std::make_shared(evtFinish))) + { + LOGWARNING("Cannot resolve google.com"); + abort(); + } + LOGD("Name lookup has been successfully queued"); + + evtFinish.Wait(); + LOGD("Network test finished"); + return 0; +} + + + + -- cgit v1.2.3 From 251c96952bb80c57f24d243def2677e3ee94efe1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 11 Jan 2015 12:59:07 +0100 Subject: cNetwork: Implemented IP-to-hostname lookup. --- tests/Network/NameLookup.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/Network/NameLookup.cpp b/tests/Network/NameLookup.cpp index daa72a3cb..74a57258c 100644 --- a/tests/Network/NameLookup.cpp +++ b/tests/Network/NameLookup.cpp @@ -25,7 +25,7 @@ class cFinishLookupCallbacks: virtual void OnError(int a_ErrorCode) override { LOGD("Error %d while performing lookup!", a_ErrorCode); - abort(); + exit(a_ErrorCode); } virtual void OnFinished(void) override @@ -49,15 +49,28 @@ int main() { cEvent evtFinish; + // Look up google.com (has multiple IP addresses): LOGD("Network test: Looking up google.com"); if (!cNetwork::HostnameToIP("google.com", std::make_shared(evtFinish))) { - LOGWARNING("Cannot resolve google.com"); + LOGWARNING("Cannot resolve google.com to IP"); abort(); } LOGD("Name lookup has been successfully queued"); - evtFinish.Wait(); + LOGD("Lookup finished."); + + // Look up 8.8.8.8 (Google free DNS): + LOGD("Network test: Looking up IP 8.8.8.8"); + if (!cNetwork::IPToHostName("8.8.8.8", std::make_shared(evtFinish))) + { + LOGWARNING("Cannot resolve 8.8.8.8 to name"); + abort(); + } + LOGD("IP lookup has been successfully queued"); + evtFinish.Wait(); + LOGD("IP lookup finished."); + LOGD("Network test finished"); return 0; } -- cgit v1.2.3 From 28e97d54684a246ce2c46197fe229cb9cb152562 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 09:38:00 +0100 Subject: cNetwork: Implemented basic server functionality. --- tests/Network/EchoServer.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index def064083..e6571a57f 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -3,6 +3,53 @@ // Implements an Echo server using the LibEvent-based cNetwork API, as a test of that API +#include "Globals.h" +#include +#include +#include "OSSupport/Network.h" + + + + + +class cEchoServerCallbacks: + public cNetwork::cListenCallbacks +{ + virtual void OnAccepted(cTCPLink & a_Link) override + { + LOGD("New client accepted, sending welcome message."); + // Send a welcome message to each connecting client: + a_Link.Send("Welcome to the simple echo server.\r\n"); + LOGD("Welcome message queued."); + } +}; + + + + + +/** cTCPLink callbacks that echo everything they receive back to the remote peer. */ +class cEchoLinkCallbacks: + public cTCPLink::cCallbacks +{ + virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Size) override + { + // Echo the incoming data back to outgoing data: + LOGD("%p: Data received (%u bytes), echoing back.", &a_Link, static_cast(a_Size)); + a_Link.Send(a_Data, a_Size); + LOGD("Echo queued"); + } + + virtual void OnRemoteClosed(cTCPLink & a_Link) override + { + LOGD("%p: Remote has closed the connection.", &a_Link); + } + + virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) override + { + LOGD("%p: Error %d in the cEchoLinkCallbacks.", &a_Link, a_ErrorCode); + } +}; @@ -10,7 +57,26 @@ int main() { - // TODO + LOGD("EchoServer: starting up"); + cServerHandlePtr Server = cNetwork::Listen(9876, std::make_shared(), std::make_shared()); + if (!Server->IsListening()) + { + LOGWARNING("Cannot listen on port 9876"); + abort(); + } + ASSERT(Server->IsListening()); + + // Wait for the user to terminate the server: + printf("Press enter to terminate the server.\n"); + AString line; + std::getline(std::cin, line); + + // Close the server and all its active connections: + LOG("Server terminating."); + Server->Close(); + ASSERT(!Server->IsListening()); + + LOG("Network test finished."); return 0; } -- cgit v1.2.3 From a2aa37bdc505c72edd5c9d41bac6e7679cea13c3 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 10:17:11 +0100 Subject: cNetwork: Implemented link address getting. --- tests/Network/EchoServer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index e6571a57f..2316d1177 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -17,7 +17,7 @@ class cEchoServerCallbacks: { virtual void OnAccepted(cTCPLink & a_Link) override { - LOGD("New client accepted, sending welcome message."); + LOGD("New client accepted (%s:%p), sending welcome message.", a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); // Send a welcome message to each connecting client: a_Link.Send("Welcome to the simple echo server.\r\n"); LOGD("Welcome message queued."); @@ -35,19 +35,19 @@ class cEchoLinkCallbacks: virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Size) override { // Echo the incoming data back to outgoing data: - LOGD("%p: Data received (%u bytes), echoing back.", &a_Link, static_cast(a_Size)); + LOGD("%p (%s:%d): Data received (%u bytes), echoing back.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), static_cast(a_Size)); a_Link.Send(a_Data, a_Size); LOGD("Echo queued"); } virtual void OnRemoteClosed(cTCPLink & a_Link) override { - LOGD("%p: Remote has closed the connection.", &a_Link); + LOGD("%p (%s:%d): Remote has closed the connection.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); } virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) override { - LOGD("%p: Error %d in the cEchoLinkCallbacks.", &a_Link, a_ErrorCode); + LOGD("%p (%s:%d): Error %d in the cEchoLinkCallbacks.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), a_ErrorCode); } }; -- cgit v1.2.3 From 9ffca127090e98f473a3a6b686804672fa0c40b0 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 10:54:28 +0100 Subject: cNetwork: Fixed Linux compilation. --- tests/Network/EchoServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index 2316d1177..3d9a6228d 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -17,7 +17,7 @@ class cEchoServerCallbacks: { virtual void OnAccepted(cTCPLink & a_Link) override { - LOGD("New client accepted (%s:%p), sending welcome message.", a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); + LOGD("New client accepted (%s:%d), sending welcome message.", a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); // Send a welcome message to each connecting client: a_Link.Send("Welcome to the simple echo server.\r\n"); LOGD("Welcome message queued."); -- cgit v1.2.3 From d8ac99a0374b528caca66ad8ecb5fb36f6334e77 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 14:58:52 +0100 Subject: cNetwork: Implemented connection shutdown and close. --- tests/Network/EchoServer.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index 3d9a6228d..1e0ac023f 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -38,6 +38,16 @@ class cEchoLinkCallbacks: LOGD("%p (%s:%d): Data received (%u bytes), echoing back.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), static_cast(a_Size)); a_Link.Send(a_Data, a_Size); LOGD("Echo queued"); + + // Search for a Ctrl+Z, if found, drop the connection: + for (size_t i = 0; i < a_Size; i++) + { + if (a_Data[i] == '\x1a') + { + a_Link.Close(); + return; + } + } } virtual void OnRemoteClosed(cTCPLink & a_Link) override @@ -67,7 +77,7 @@ int main() ASSERT(Server->IsListening()); // Wait for the user to terminate the server: - printf("Press enter to terminate the server.\n"); + printf("Press enter to close the server.\n"); AString line; std::getline(std::cin, line); @@ -75,6 +85,10 @@ int main() LOG("Server terminating."); Server->Close(); ASSERT(!Server->IsListening()); + LOGD("Server has been closed."); + + printf("Press enter to exit test.\n"); + std::getline(std::cin, line); LOG("Network test finished."); return 0; -- cgit v1.2.3 From ddb1818dd54d82e19e7f629e6a729bccb68bfcf1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 15:45:30 +0100 Subject: cNetwork: Added multithreading protection. --- tests/Network/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Network/CMakeLists.txt b/tests/Network/CMakeLists.txt index a63ce7dfe..9d0dcdc24 100644 --- a/tests/Network/CMakeLists.txt +++ b/tests/Network/CMakeLists.txt @@ -6,7 +6,13 @@ include_directories(${CMAKE_SOURCE_DIR}/src/) include_directories(${CMAKE_SOURCE_DIR}/lib/libevent/include) add_definitions(-DTEST_GLOBALS=1) -add_library(Network ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp) +add_library(Network + ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp + ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp +) + target_link_libraries(Network event_core event_extra) if (MSVC) target_link_libraries(Network ws2_32.lib) -- cgit v1.2.3 From 7cddb6237418f2d7ec984cd0d4cbdac7140330b0 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 15 Jan 2015 21:10:14 +0100 Subject: cNetwork: Added an OnError callback for listening servers. The callback receives the error details. --- tests/Network/EchoServer.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index 1e0ac023f..333c31e08 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -22,6 +22,11 @@ class cEchoServerCallbacks: a_Link.Send("Welcome to the simple echo server.\r\n"); LOGD("Welcome message queued."); } + + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override + { + LOGWARNING("An error occured while listening for connections: %d (%s).", a_ErrorCode, a_ErrorMsg.c_str()); + } }; -- cgit v1.2.3 From d3076a3e1664c6a6e7c0d4cf24ac4335bb0a3899 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 17 Jan 2015 23:33:59 +0100 Subject: cNetwork: Split cNetworkSingleton to a separate file. --- tests/Network/CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Network/CMakeLists.txt b/tests/Network/CMakeLists.txt index 9d0dcdc24..6bf291544 100644 --- a/tests/Network/CMakeLists.txt +++ b/tests/Network/CMakeLists.txt @@ -6,10 +6,13 @@ include_directories(${CMAKE_SOURCE_DIR}/src/) include_directories(${CMAKE_SOURCE_DIR}/lib/libevent/include) add_definitions(-DTEST_GLOBALS=1) + +# Create a single Network library that contains all the networking code: add_library(Network - ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp ) @@ -18,12 +21,20 @@ if (MSVC) target_link_libraries(Network ws2_32.lib) endif() + + + +# Define individual tests: + +# Google: download the google.com frontpage using http client socket: add_executable(Google-exe Google.cpp) target_link_libraries(Google-exe Network) add_test(NAME Google-test COMMAND Google-exe) +# EchoServer: Listen on port 9876, echo everything back: add_executable(EchoServer EchoServer.cpp) target_link_libraries(EchoServer Network) +# NameLookup: Lookup hostname-to-IP and IP-to-hostname: add_executable(NameLookup NameLookup.cpp) target_link_libraries(NameLookup Network) -- cgit v1.2.3 From c0cb787c101725a649d26de68fca2632c82830ba Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 18 Jan 2015 11:57:16 +0100 Subject: cNetwork: Split the main cpp file into several files. --- tests/Network/CMakeLists.txt | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/Network/CMakeLists.txt b/tests/Network/CMakeLists.txt index 6bf291544..c0af50e2c 100644 --- a/tests/Network/CMakeLists.txt +++ b/tests/Network/CMakeLists.txt @@ -8,14 +8,34 @@ include_directories(${CMAKE_SOURCE_DIR}/lib/libevent/include) add_definitions(-DTEST_GLOBALS=1) # Create a single Network library that contains all the networking code: -add_library(Network +set (Network_SRCS ${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp - ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/HostnameLookup.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/IPLookup.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.cpp + ${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp ) +set (Network_HDRS + ${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/Event.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/HostnameLookup.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/IPLookup.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/Network.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.h + ${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.h + ${CMAKE_SOURCE_DIR}/src/StringUtils.h +) + +add_library(Network + ${Network_SRCS} + ${Network_HDRS} +) + target_link_libraries(Network event_core event_extra) if (MSVC) target_link_libraries(Network ws2_32.lib) -- cgit v1.2.3 From d4682463a1d503c349ac95e275b11d67d402268c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 18 Jan 2015 12:35:02 +0100 Subject: cNetwork: Fixed race conditions with lookups; proper shutdown. --- tests/Network/Google.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/Network/Google.cpp b/tests/Network/Google.cpp index de5f95e1f..8ee04f8ee 100644 --- a/tests/Network/Google.cpp +++ b/tests/Network/Google.cpp @@ -95,6 +95,7 @@ int main() evtFinish.Wait(); LOGD("Network test finished"); + return 0; } -- cgit v1.2.3 From 64855ed340e76779b99f37fbc866a7f5952e11db Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 20 Jan 2015 11:27:05 +0100 Subject: cNetwork: Added error message to error callbacks. --- tests/Network/EchoServer.cpp | 4 ++-- tests/Network/Google.cpp | 8 ++++---- tests/Network/NameLookup.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index 333c31e08..86b517245 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -60,9 +60,9 @@ class cEchoLinkCallbacks: LOGD("%p (%s:%d): Remote has closed the connection.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); } - virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) override + virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) override { - LOGD("%p (%s:%d): Error %d in the cEchoLinkCallbacks.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), a_ErrorCode); + LOGD("%p (%s:%d): Error %d in the cEchoLinkCallbacks: %s", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), a_ErrorCode, a_ErrorMsg.c_str()); } }; diff --git a/tests/Network/Google.cpp b/tests/Network/Google.cpp index 8ee04f8ee..be08f179c 100644 --- a/tests/Network/Google.cpp +++ b/tests/Network/Google.cpp @@ -27,9 +27,9 @@ class cHTTPConnectCallbacks: LOGD("HTTP GET queued."); } - virtual void OnError(int a_ErrorCode) override + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override { - LOGD("Error while connecting HTTP: %d", a_ErrorCode); + LOGD("Error while connecting HTTP: %d (%s)", a_ErrorCode, a_ErrorMsg.c_str()); m_Event.Set(); } @@ -64,9 +64,9 @@ class cDumpCallbacks: m_Event.Set(); } - virtual void OnError(cTCPLink & a_Link, int a_ErrorCode) override + virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) override { - LOGD("Error in the cDumpCallbacks."); + LOGD("Error %d (%s) in the cDumpCallbacks.", a_ErrorCode, a_ErrorMsg.c_str()); m_Event.Set(); } diff --git a/tests/Network/NameLookup.cpp b/tests/Network/NameLookup.cpp index 74a57258c..822a96baf 100644 --- a/tests/Network/NameLookup.cpp +++ b/tests/Network/NameLookup.cpp @@ -22,9 +22,9 @@ class cFinishLookupCallbacks: LOGD("%s resolves to IP %s", a_Name.c_str(), a_IP.c_str()); } - virtual void OnError(int a_ErrorCode) override + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override { - LOGD("Error %d while performing lookup!", a_ErrorCode); + LOGD("Error %d (%s) while performing lookup!", a_ErrorCode, a_ErrorMsg.c_str()); exit(a_ErrorCode); } -- cgit v1.2.3 From 5b4c5cf2befebb78ff2b16955c244e79841648a7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 21 Jan 2015 21:12:11 +0100 Subject: cNetwork: Changed listening API. The link-callbacks for each new accepted link are now received from the OnIncomingConnection listen-callback. --- tests/Network/EchoServer.cpp | 50 +++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index 86b517245..061310c82 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -12,27 +12,6 @@ -class cEchoServerCallbacks: - public cNetwork::cListenCallbacks -{ - virtual void OnAccepted(cTCPLink & a_Link) override - { - LOGD("New client accepted (%s:%d), sending welcome message.", a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); - // Send a welcome message to each connecting client: - a_Link.Send("Welcome to the simple echo server.\r\n"); - LOGD("Welcome message queued."); - } - - virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override - { - LOGWARNING("An error occured while listening for connections: %d (%s).", a_ErrorCode, a_ErrorMsg.c_str()); - } -}; - - - - - /** cTCPLink callbacks that echo everything they receive back to the remote peer. */ class cEchoLinkCallbacks: public cTCPLink::cCallbacks @@ -70,10 +49,37 @@ class cEchoLinkCallbacks: +class cEchoServerCallbacks: + public cNetwork::cListenCallbacks +{ + virtual cTCPLink::cCallbacksPtr OnIncomingConnection(const AString & a_RemoteIPAddress, UInt16 a_RemotePort) + { + LOGD("New incoming connection(%s:%d).", a_RemoteIPAddress.c_str(), a_RemotePort); + return std::make_shared(); + } + + virtual void OnAccepted(cTCPLink & a_Link) override + { + LOGD("New client accepted (%s:%d), sending welcome message.", a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); + // Send a welcome message to each connecting client: + a_Link.Send("Welcome to the simple echo server.\r\n"); + LOGD("Welcome message queued."); + } + + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override + { + LOGWARNING("An error occured while listening for connections: %d (%s).", a_ErrorCode, a_ErrorMsg.c_str()); + } +}; + + + + + int main() { LOGD("EchoServer: starting up"); - cServerHandlePtr Server = cNetwork::Listen(9876, std::make_shared(), std::make_shared()); + cServerHandlePtr Server = cNetwork::Listen(9876, std::make_shared()); if (!Server->IsListening()) { LOGWARNING("Cannot listen on port 9876"); -- cgit v1.2.3 From dbf7f13bd414daea5e787da2543df186dc465c34 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 22 Jan 2015 13:00:32 +0100 Subject: cNetwork: Added link creation callback. This allows the callback classes to store the link inside them and use it internally later on, mainly for sending data. --- tests/Network/EchoServer.cpp | 38 ++++++++++++++++++++++++++++++-------- tests/Network/Google.cpp | 21 ++++++++++++++++++--- 2 files changed, 48 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/Network/EchoServer.cpp b/tests/Network/EchoServer.cpp index 061310c82..728db0b7c 100644 --- a/tests/Network/EchoServer.cpp +++ b/tests/Network/EchoServer.cpp @@ -16,11 +16,21 @@ class cEchoLinkCallbacks: public cTCPLink::cCallbacks { - virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Size) override + // cTCPLink::cCallbacks overrides: + virtual void OnLinkCreated(cTCPLinkPtr a_Link) override { + ASSERT(m_Link == nullptr); + m_Link = a_Link; + } + + + virtual void OnReceivedData(const char * a_Data, size_t a_Size) override + { + ASSERT(m_Link != nullptr); + // Echo the incoming data back to outgoing data: - LOGD("%p (%s:%d): Data received (%u bytes), echoing back.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), static_cast(a_Size)); - a_Link.Send(a_Data, a_Size); + LOGD("%p (%s:%d): Data received (%u bytes), echoing back.", m_Link.get(), m_Link->GetRemoteIP().c_str(), m_Link->GetRemotePort(), static_cast(a_Size)); + m_Link->Send(a_Data, a_Size); LOGD("Echo queued"); // Search for a Ctrl+Z, if found, drop the connection: @@ -28,21 +38,33 @@ class cEchoLinkCallbacks: { if (a_Data[i] == '\x1a') { - a_Link.Close(); + m_Link->Close(); + m_Link.reset(); return; } } } - virtual void OnRemoteClosed(cTCPLink & a_Link) override + + virtual void OnRemoteClosed(void) override { - LOGD("%p (%s:%d): Remote has closed the connection.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()); + ASSERT(m_Link != nullptr); + + LOGD("%p (%s:%d): Remote has closed the connection.", m_Link.get(), m_Link->GetRemoteIP().c_str(), m_Link->GetRemotePort()); + m_Link.reset(); } - virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) override + + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override { - LOGD("%p (%s:%d): Error %d in the cEchoLinkCallbacks: %s", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), a_ErrorCode, a_ErrorMsg.c_str()); + ASSERT(m_Link != nullptr); + + LOGD("%p (%s:%d): Error %d in the cEchoLinkCallbacks: %s", m_Link.get(), m_Link->GetRemoteIP().c_str(), m_Link->GetRemotePort(), a_ErrorCode, a_ErrorMsg.c_str()); + m_Link.reset(); } + + /** The link attached to this callbacks instance. */ + cTCPLinkPtr m_Link; }; diff --git a/tests/Network/Google.cpp b/tests/Network/Google.cpp index be08f179c..8985eef17 100644 --- a/tests/Network/Google.cpp +++ b/tests/Network/Google.cpp @@ -49,24 +49,39 @@ class cDumpCallbacks: public cTCPLink::cCallbacks { cEvent & m_Event; + cTCPLinkPtr m_Link; - virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Size) override + virtual void OnLinkCreated(cTCPLinkPtr a_Link) override { + ASSERT(m_Link == nullptr); + m_Link = a_Link; + } + + virtual void OnReceivedData(const char * a_Data, size_t a_Size) override + { + ASSERT(m_Link != nullptr); + // Log the incoming data size: AString Hex; CreateHexDump(Hex, a_Data, a_Size, 16); LOGD("Incoming data: %u bytes:\n%s", static_cast(a_Size), Hex.c_str()); } - virtual void OnRemoteClosed(cTCPLink & a_Link) override + virtual void OnRemoteClosed(void) override { + ASSERT(m_Link != nullptr); + LOGD("Remote has closed the connection."); + m_Link.reset(); m_Event.Set(); } - virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) override + virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override { + ASSERT(m_Link != nullptr); + LOGD("Error %d (%s) in the cDumpCallbacks.", a_ErrorCode, a_ErrorMsg.c_str()); + m_Link.reset(); m_Event.Set(); } -- cgit v1.2.3 From 9014bdfa3233dac70274b27eb40df3739b6f49eb Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 22 Jan 2015 22:49:37 +0100 Subject: cNetwork: Renamed callback to OnConnected() --- tests/Network/Google.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Network/Google.cpp b/tests/Network/Google.cpp index 8985eef17..2b8830c24 100644 --- a/tests/Network/Google.cpp +++ b/tests/Network/Google.cpp @@ -17,7 +17,7 @@ class cHTTPConnectCallbacks: public cNetwork::cConnectCallbacks { cEvent & m_Event; - virtual void OnSuccess(cTCPLink & a_Link) override + virtual void OnConnected(cTCPLink & a_Link) override { LOGD("Connected, sending HTTP GET"); if (!a_Link.Send("GET / HTTP/1.0\r\nHost:google.com\r\n\r\n")) -- cgit v1.2.3