From 7d0b48d7bf614262c295c2aa2930f8cad18669fa Mon Sep 17 00:00:00 2001 From: steffen Date: Sun, 18 Oct 2020 19:47:39 +0000 Subject: [PATCH] added better windows support --- Changelog | 1 + Makefile | 4 ++- Makefile.rules.linux | 2 +- Makefile.rules.windows | 2 +- UDPTCPNetwork.h | 19 +++++++----- network.cc | 27 +++++++++++++++++ tcp.cc | 24 +++++++++++---- test-tcpclient.cc | 65 ++++++++++++++++++++++++++++++++++++++++ test-tcpserver.cc | 67 ++++++++++++++++++++++++++++++++++++++++++ udp.cc | 1 + 10 files changed, 196 insertions(+), 16 deletions(-) create mode 100644 test-tcpclient.cc create mode 100644 test-tcpserver.cc diff --git a/Changelog b/Changelog index f6e656c..7cb8580 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,5 @@ 2020-10-18: +- fixed windows support with TCP sockets. Needed to call closesocket on windows. - added support for windows. Everything should work but UNIX sockets. 2020-10-15: diff --git a/Makefile b/Makefile index b37e35b..afd2348 100644 --- a/Makefile +++ b/Makefile @@ -67,11 +67,13 @@ dep: clean: rm Makefile.rules -rf - rm test-tcp -rf + rm test-tcpserver -rf + rm test-tcpclient -rf rm test-udp -rf rm test-ssl -rf rm -rf gmon.out rm *.s -rf + rm *.exe -rf rm *.o -rf rm *.oo -rf rm *~ -rf diff --git a/Makefile.rules.linux b/Makefile.rules.linux index 556356f..c1c1a4f 100644 --- a/Makefile.rules.linux +++ b/Makefile.rules.linux @@ -5,7 +5,7 @@ ETCPREFIX = /etc LINUXVERSION = 1 CXX = g++ -CXXFLAGS = -ggdb -fPIC -pg -Wno-write-strings -I./ -std=c++11 -DBUILD_LINUX +CXXFLAGS = -ggdb -fPIC -pg -Wno-write-strings -I./ -std=c++11 -DBUILD_LINUX=1 LDFLAGS = -lm -pg -lssl -lcrypto TARGET = lib$(OBJLIB_NAME).so.$(VERSION) diff --git a/Makefile.rules.windows b/Makefile.rules.windows index e6a848d..ac418a4 100644 --- a/Makefile.rules.windows +++ b/Makefile.rules.windows @@ -4,7 +4,7 @@ PREFIX = /usr ETCPREFIX = /etc WINVERSION = 1 CXX = g++ -CXXFLAGS = -ggdb -fPIC -Wno-write-strings -I./ -std=c++11 -DBUILD_WINDOWS +CXXFLAGS = -ggdb -fPIC -Wno-write-strings -I./ -std=c++11 -DBUILD_WINDOWS=1 LDFLAGS = -lm -lssl -lcrypto -lwsock32 -lws2_32 TARGET = $(OBJLIB_NAME).dll diff --git a/UDPTCPNetwork.h b/UDPTCPNetwork.h index 20fec16..9c30b56 100644 --- a/UDPTCPNetwork.h +++ b/UDPTCPNetwork.h @@ -4,6 +4,8 @@ #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN + #define _NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000 #define _NTDDI_VERSION_FROM_WIN32_WINNT(ver) _NTDDI_VERSION_FROM_WIN32_WINNT2(ver) @@ -45,6 +47,8 @@ using namespace std; +#define SOCKET int + #define NET_HOSTLEN 256 #define NET_PORTLEN 6 #define NET_BUFFERSIZE 1024 @@ -60,8 +64,9 @@ using namespace std; int dns_filladdr (string host, string port, int ai_family, struct sockaddr_storage *sAddr); char *itoa(char* buffer, int number, int size); - - +void UDPTCPNetwork_Startup(); +extern int UDPTCPNetwork_init; +#define UDPTCPNetwork() if(UDPTCPNetwork_init == 0) UDPTCPNetwork_Startup() /************************************************************************ * @@ -70,7 +75,7 @@ char *itoa(char* buffer, int number, int size); */ class UDP { private: - int sock; + SOCKET sock; int localport; size_t readcnt; size_t writecnt; @@ -99,7 +104,7 @@ public: */ class TCP { private: - int sock; + SOCKET sock; string remote_host; string remote_port; int readcnt; @@ -107,7 +112,7 @@ private: int islisten; public: TCP(); - TCP(int s); + TCP(SOCKET s); TCP(string h, string p); TCP(string hostport, int defaultport); ~TCP(); @@ -127,8 +132,8 @@ public: int Listen(int port); TCP* Accept(); - int GetSocket() { return sock; }; - void SetSocket(int s, struct sockaddr_storage *saddr, int saddrlen); + SOCKET GetSocket() { return sock; }; + void SetSocket(SOCKET s, struct sockaddr_storage *saddr, int saddrlen); const string GetRemoteAddr(); const string GetLocalAddr(); diff --git a/network.cc b/network.cc index 9197d0b..8a430df 100644 --- a/network.cc +++ b/network.cc @@ -8,6 +8,7 @@ using namespace std; char dnsip[NET_HOSTLEN]; +int UDPTCPNetwork_init = 0; // // convert host and port to sockaddr_in6 @@ -39,3 +40,29 @@ char* itoa(char* buffer, int number, int size) { snprintf (buffer, size, "%d", number); return buffer; } + + +void UDPTCPNetwork_Startup() { + if (UDPTCPNetwork_init != 0) return; + + printf ("%s\n", __FUNCTION__); + +#ifdef BUILD_WINDOWS + + WORD wVersionRequested; + WSADATA wsaData; + int err; + +/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + printf("WSAStartup failed with error: %d\n", err); + return; + } +#endif + UDPTCPNetwork_init = 1; +} diff --git a/tcp.cc b/tcp.cc index c3dab00..e7f417a 100644 --- a/tcp.cc +++ b/tcp.cc @@ -15,6 +15,7 @@ TCP::~TCP() { } TCP::TCP() { + UDPTCPNetwork(); sock = 0; writecnt = 0; readcnt = 0; @@ -93,7 +94,8 @@ int TCP::Listen(int port) { TCP* TCP::Accept() { fd_set rfds; struct timeval tv; - int retval, newsock, err, i; + int retval, err, i; + SOCKET newsock; struct sockaddr_storage cli_addr; unsigned int cli_len = sizeof(cli_addr); char host[NET_BUFFERSIZE]; @@ -121,9 +123,13 @@ TCP* TCP::Accept() { #else newsock = accept (sock, (struct sockaddr *) &cli_addr, &cli_len); #endif + printf ("%s:%d newsock:%d", __FILE__, __LINE__, newsock); + if (newsock < 0) return NULL; tcp = new TCP(); tcp->SetSocket(newsock, &cli_addr, cli_len); + printf ("%s:%d setup TCP object sock:%d", __FILE__, __LINE__, tcp->GetSocket()); + return tcp; } return NULL; @@ -220,12 +226,16 @@ long int TCP::Read(char *buffer, long int len) { long int len_ = len; if (sock <= 0) return -2; - len_ = read (sock, (void*)buffer, len); - // printf ("read: "); debug_mem(buffer, len_); + len_ = recv (sock, buffer, len, 0); + printf ("read: %d\n", len_); if (len_ < 0 && errno == EAGAIN) len_ = 0; else if (len_ < 0 && errno != EAGAIN) { - // fprintf (stderr, "%s ERROR:%s\n", __FUNCTION__, strerror (errno)); +#ifdef BUILD_WINDOWS + printf ("%s ERROR:%s\n", __FUNCTION__, strerror (errno)); +#else + fprintf (stderr, "%s ERROR:%s\n", __FUNCTION__, strerror (errno)); +#endif len_ = -2; } else if (len_ == 0) len_ = -1; @@ -267,7 +277,11 @@ long int TCP::Write(char *buffer, long int len) { void TCP::Close() { +#ifdef BUILD_WINDOWS + closesocket(sock); +#else if (sock > 0) close (sock); +#endif sock = -1; islisten = false; }; @@ -445,8 +459,6 @@ const string TCP::GetRemoteAddr() { const string TCP::GetLocalAddr() { string ret; - - return ret; }; diff --git a/test-tcpclient.cc b/test-tcpclient.cc new file mode 100644 index 0000000..eeeb63f --- /dev/null +++ b/test-tcpclient.cc @@ -0,0 +1,65 @@ + +#include +#include + +#include "UDPTCPNetwork.h" + +#define DEFAULT_PORT 12345 + +int main (int argc, char **argv) { + TCP tcpclient; + char buffer[NET_BUFFERSIZE]; + int i; + +#ifdef BUILD_WINDOWS + char iobuffer[16]; + setvbuf (stdout, iobuffer, _IONBF, 16); +#endif + + // + // connect to the server + if (argc == 2) { + if (tcpclient.Connect(argv[1], DEFAULT_PORT) != 1) { + printf ("connect to: %s:%s\n",argv[1], DEFAULT_PORT); + printf ("cloud not connect to server\n"); + exit (1); + } + } + else if (argc == 3) { + printf ("connect to: %s:%s\n",argv[1], atoi(argv[2])); + if (tcpclient.Connect(argv[1], argv[2]) != 1) { + printf ("cloud not connect to server\n"); + exit (1); + } + } + else { + printf ("\nplease use the ollowing commands:\n\n"); + printf (" test-tcpclient destination\n"); + printf (" test-tcpclient destination port\n"); + return 1; + } + + // + // send some data + snprintf (buffer, NET_BUFFERSIZE, "nur ein kleiner Test."); + printf ("client:send '%s' to the server.\n", buffer); + if (tcpclient.Write(buffer, strlen (buffer)) != strlen (buffer)) { + printf ("could not send all data.\n"); + exit (1); + } + + // + // read some data (wait maximum 10x1000ms) + for (i = 10; i > 0; i--) + if (tcpclient.ReadTimeout(buffer, NET_BUFFERSIZE, 1000) > 0) { + printf ("client:got '%s' from server.\n", buffer); + break; + } + + // + // close connection + tcpclient.Close(); + + return 0; +}; + diff --git a/test-tcpserver.cc b/test-tcpserver.cc new file mode 100644 index 0000000..8b9fe63 --- /dev/null +++ b/test-tcpserver.cc @@ -0,0 +1,67 @@ + +#include +#include + +#include "UDPTCPNetwork.h" + +#define DEFAULT_PORT 12345 + +int main(int argc, char **argv) { + TCP tcpserver; + TCP *connection = NULL; + int i, timeout; + pid_t pid; + time_t time_start = time (NULL); + time_t time_now = time (NULL); + char buffer[NET_BUFFERSIZE]; + +#ifdef BUILD_WINDOWS + char iobuffer[16]; + setvbuf (stdout, iobuffer, _IONBF, 16); +#endif + + + // + // start the server + if (tcpserver.Listen(DEFAULT_PORT) != 1) { + printf ("cloud not start the tcp server\n"); + exit (1); + } + + printf ("server started\n"); + + // + // check for connections + while(1) { + if (connection == NULL) { + connection = tcpserver.Accept(); + if (connection != NULL) + printf (" server: got a new connection\n"); + } + + if (connection != NULL) { + i = connection->Read(buffer, NET_BUFFERSIZE); + if (i >= 0) { + int c; + + printf (" server: (child) got: '%s'\n", buffer); + for (c = 0; c < i; c++) buffer[c] = toupper(buffer[c]); + connection->Write(buffer, i); + } + else { + printf (" server: (child) got: nothing (i:%d)\n", i); + delete connection; + connection = NULL; + } + } + else { + // + // parent process - just close the client connection + // it will be handeled by the child process. + printf ("no connection\n"); + } + usleep (25000); + } + tcpserver.Close(); +}; + diff --git a/udp.cc b/udp.cc index a40ab5a..f340841 100644 --- a/udp.cc +++ b/udp.cc @@ -12,6 +12,7 @@ #include "UDPTCPNetwork.h" UDP::UDP() { + UDPTCPNetwork(); sock = -1; localport = -1; writecnt = 0;