From 9e0421a8220870a8198a4b0a3657ffad544d366b Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 7 Oct 2016 00:35:43 +0200 Subject: [PATCH] [DEV] windows port functionnal and update Linux to support select on linux insated of poll --- enet/Tcp.cpp | 124 ++++++++++++++------------------- enet/Tcp.hpp | 7 -- enet/TcpClient.cpp | 5 +- enet/TcpServer.cpp | 2 +- enet/enet.cpp | 4 +- test/main-client-http.cpp | 9 +-- test/main-client-websocket.cpp | 7 +- test/main-client.cpp | 14 ++-- test/main-server-http.cpp | 6 +- test/main-server-websocket.cpp | 6 +- test/main-server.cpp | 8 +-- 11 files changed, 82 insertions(+), 110 deletions(-) diff --git a/enet/Tcp.cpp b/enet/Tcp.cpp index c2a7bdd..e5f390e 100644 --- a/enet/Tcp.cpp +++ b/enet/Tcp.cpp @@ -53,13 +53,7 @@ enet::Tcp::Tcp() : m_socketId(_idSocket), m_name(_name), m_status(status::link) { - //Initialize the pollfd structure - memset(&m_fds[0], 0 , sizeof(m_fds)); - //Set up the initial listening socket - #ifndef __TARGET_OS__Windows - m_fds[0].fd = _idSocket; - m_fds[0].events = POLLIN | POLLERR; - #endif + } enet::Tcp::Tcp(Tcp&& _obj) : @@ -73,10 +67,6 @@ enet::Tcp::Tcp(Tcp&& _obj) : #endif _obj.m_name = ""; _obj.m_status = status::error; - #ifndef __TARGET_OS__Windows - m_fds[0] = _obj.m_fds[0]; - memset(&m_fds[0], 0 , sizeof(m_fds)); - #endif } enet::Tcp::~Tcp() { @@ -95,10 +85,6 @@ enet::Tcp& enet::Tcp::operator = (enet::Tcp&& _obj) { _obj.m_name = ""; m_status = _obj.m_status; _obj.m_status = status::error; - #ifndef __TARGET_OS__Windows - m_fds[0] = _obj.m_fds[0]; - memset(&m_fds[0], 0 , sizeof(m_fds)); - #endif return *this; } @@ -107,16 +93,14 @@ bool enet::Tcp::unlink() { ENET_INFO("Close socket (start)"); #ifdef __TARGET_OS__Windows shutdown(m_socketId, SD_BOTH); + closesocket(m_socketId); + m_socketId = INVALID_SOCKET; #else shutdown(m_socketId, SHUT_RDWR); - #endif - #ifdef __TARGET_OS__Windows - closesocket(m_socketId); - #else close(m_socketId); + m_socketId = -1; #endif ENET_INFO("Close socket (done)"); - m_socketId = -1; } m_status = status::unlink; return true; @@ -129,54 +113,58 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) { return -1; } int32_t size = -1; + + fd_set sock; // Initialize the timeout to 3 minutes. If no activity after 3 minutes this program will end. timeout value is based on milliseconds. - int timeout = (3 * 60 * 1000); - #ifdef __TARGET_OS__Windows - - #else - int nfds = 1; - // Call poll() and wait 3 minutes for it to complete. - int rc = poll(m_fds, nfds, timeout); - // Check to see if the poll call failed. - if (rc < 0) { - ENET_ERROR(" poll() failed"); - return-1; - } - // Check to see if the 3 minute time out expired. - if (rc == 0) { - ENET_ERROR(" poll() timed out.\n"); - return -2; - } - bool closeConn = false; - // Receive all incoming data on this socket before we loop back and call poll again. - // Receive data on this connection until the recv fails with EWOULDBLOCK. - // If any other failure occurs, we will close the connection. - { - std::unique_lock lock(m_mutex); - //ENET_DEBUG("Read on socketid = " << m_fds[0].fd ); - rc = recv(m_fds[0].fd, _data, _maxLen, 0); - } - if (rc < 0) { - if (errno != EWOULDBLOCK) { - ENET_ERROR(" recv() failed"); - closeConn = true; - } - } - // Check to see if the connection has been closed by the client - if (rc == 0) { - ENET_INFO("Connection closed"); + struct timeval timeOutStruct; + timeOutStruct.tv_sec = (3 * 60 * 1000); + timeOutStruct.tv_usec = 0; + FD_ZERO(&sock); + FD_SET(m_socketId,&sock); + int rc = select(m_socketId+1, &sock, NULL, NULL, &timeOutStruct); + // Check to see if the poll call failed. + if (rc < 0) { + ENET_ERROR(" select() failed"); + return -1; + } + // Check to see if the 3 minute time out expired. + if (rc == 0) { + ENET_ERROR(" select() timed out."); + return -2; + } + if (!FD_ISSET(m_socketId, &sock)) { + ENET_ERROR(" select() id is not set..."); + return -1; + } + bool closeConn = false; + // Receive all incoming data on this socket before we loop back and call poll again. + // Receive data on this connection until the recv fails with EWOULDBLOCK. + // If any other failure occurs, we will close the connection. + { + std::unique_lock lock(m_mutex); + rc = recv(m_socketId, (char *)_data, _maxLen, 0); + } + if (rc < 0) { + if (errno != EWOULDBLOCK) { + ENET_ERROR(" recv() failed"); closeConn = true; } - if (closeConn == false) { - // Data was received - size = rc; - } else { - // If the close_conn flag was turned on, we need to clean up this active connection. - // This clean up process includes removing the descriptor. - ENET_DEBUG(" Set status at remote close ..."); - m_status = status::linkRemoteClose; - } - #endif + } + // Check to see if the connection has been closed by the client + if (rc == 0) { + ENET_INFO("Connection closed"); + closeConn = true; + } + if (closeConn == false) { + // Data was received + size = rc; + } else { + // If the close_conn flag was turned on, we need to clean up this active connection. + // This clean up process includes removing the descriptor. + ENET_DEBUG(" Set status at remote close ..."); + m_status = status::linkRemoteClose; + } + //#endif return size; } @@ -190,11 +178,7 @@ int32_t enet::Tcp::write(const void* _data, int32_t _len) { int32_t size; { std::unique_lock lock(m_mutex); - #ifdef __TARGET_OS__Windows - size = ::send(m_socketId, (const char *)_data, _len, 0); - #else - size = ::write(m_socketId, _data, _len); - #endif + size = ::send(m_socketId, (const char *)_data, _len, 0); } if ( size != _len && errno != 0) { diff --git a/enet/Tcp.hpp b/enet/Tcp.hpp index 59169e5..f97d876 100644 --- a/enet/Tcp.hpp +++ b/enet/Tcp.hpp @@ -10,8 +10,6 @@ #ifdef __TARGET_OS__Windows #include #include -#else - #include #endif namespace enet { @@ -22,11 +20,6 @@ namespace enet { #else int32_t m_socketId; //!< socket linux interface generic #endif - #ifdef __TARGET_OS__Windows - int32_t m_fds[1]; - #else - struct pollfd m_fds[1]; - #endif std::mutex m_mutex; public: Tcp(); diff --git a/enet/TcpClient.cpp b/enet/TcpClient.cpp index 72a5462..2442a2d 100644 --- a/enet/TcpClient.cpp +++ b/enet/TcpClient.cpp @@ -71,6 +71,7 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8 for(struct addrinfo* ptr=result; ptr != nullptr; ptr=ptr->ai_next) { + ENET_DEBUG(" find one ..."); // Create a SOCKET for connecting to server socketId = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (socketId == INVALID_SOCKET) { @@ -80,6 +81,7 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8 // Connect to server. iResult = connect(socketId, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { + ENET_ERROR("socket connection failed with error: " << WSAGetLastError()); closesocket(socketId); socketId = INVALID_SOCKET; continue; @@ -90,9 +92,10 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8 if (socketId == INVALID_SOCKET) { ENET_ERROR("Unable to connect to server!"); - WSACleanup(); usleep(200000); continue; + } else { + break; } } if (socketId == INVALID_SOCKET) { diff --git a/enet/TcpServer.cpp b/enet/TcpServer.cpp index b386fcc..141a324 100644 --- a/enet/TcpServer.cpp +++ b/enet/TcpServer.cpp @@ -88,7 +88,7 @@ void enet::TcpServer::setPort(uint16_t _port) { // open in Socket normal mode m_socketId = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - if (m_socketId != INVALID_SOCKET) { + if (m_socketId == INVALID_SOCKET) { ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno)); freeaddrinfo(result); return false; diff --git a/enet/enet.cpp b/enet/enet.cpp index def1940..0ab80b8 100644 --- a/enet/enet.cpp +++ b/enet/enet.cpp @@ -36,7 +36,7 @@ void enet::init(int _argc, const char** _argv) { } } -void unInit() { +void enet::unInit() { if (getInitSatatus() == false) { ENET_ERROR("Request UnInit of enent already done ..."); } else { @@ -48,7 +48,7 @@ void unInit() { } -bool isInit() { +bool enet::isInit() { return getInitSatatus(); } diff --git a/test/main-client-http.cpp b/test/main-client-http.cpp index f330dd5..a8eeef6 100644 --- a/test/main-client-http.cpp +++ b/test/main-client-http.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -22,6 +23,7 @@ namespace appl { int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); + enet::init(_argc, _argv); for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if ( data == "-h" @@ -35,7 +37,6 @@ int main(int _argc, const char *_argv[]) { TEST_INFO("=================================="); TEST_INFO("== Test HTTP client =="); TEST_INFO("=================================="); -#ifndef __TARGET_OS__Windows // connect on TCP server: enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); // TODO : Check if connection is valid ... @@ -47,16 +48,12 @@ int main(int _argc, const char *_argv[]) { // start http connection (the actual state is just TCP start ...) connection.start(); - enet::HttpRequest req(enet::HTTPReqType::GET); + enet::HttpRequest req(enet::HTTPReqType::HTTP_GET); req.setUri("plop.txt"); connection.setHeader(req); while (connection.isAlive() == true) { usleep(100000); } - -#else - TEST_CRITICAL("not implemented"); -#endif return 0; } diff --git a/test/main-client-websocket.cpp b/test/main-client-websocket.cpp index ec74418..f3172ed 100644 --- a/test/main-client-websocket.cpp +++ b/test/main-client-websocket.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -29,6 +30,7 @@ namespace appl { int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); + enet::init(_argc, _argv); for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if ( data == "-h" @@ -42,7 +44,6 @@ int main(int _argc, const char *_argv[]) { TEST_INFO("=================================="); TEST_INFO("== Test WebSocket client =="); TEST_INFO("=================================="); -#ifndef __TARGET_OS__Windows // connect on TCP server: enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); // TODO : Check if connection is valid ... @@ -68,9 +69,5 @@ int main(int _argc, const char *_argv[]) { usleep(100000); timeout--; } - -#else - TEST_CRITICAL("not implemented"); -#endif return 0; } diff --git a/test/main-client.cpp b/test/main-client.cpp index 4af0ee8..d1a6c3b 100644 --- a/test/main-client.cpp +++ b/test/main-client.cpp @@ -5,15 +5,17 @@ */ #include +#include #include #include #include #include - +#include #include int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); + enet::init(_argc, _argv); for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if ( data == "-h" @@ -27,7 +29,6 @@ int main(int _argc, const char *_argv[]) { TEST_INFO("=================================="); TEST_INFO("== Test TCP client =="); TEST_INFO("=================================="); -#ifndef __TARGET_OS__Windows // client mode ... // connect on TCP server: enet::Tcp connection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); @@ -37,12 +38,18 @@ int main(int _argc, const char *_argv[]) { return -1; } int32_t iii = 0; + int32_t delay = 200; while ( connection.getConnectionStatus() == enet::Tcp::status::link && iii<10000) { char data[1024]; int32_t len = connection.read(data, 1024); TEST_INFO("read len=" << len << " data='" << data << "'"); //if (data[len-1] == '2') { + std::this_thread::sleep_for(std::chrono::milliseconds(delay)); + delay--; + if (delay == 0) { + delay = 500; + } int32_t lenWrite = connection.write("get pair value"); TEST_INFO("write len=" << lenWrite); //} @@ -59,8 +66,5 @@ int main(int _argc, const char *_argv[]) { TEST_ERROR("can not unlink to the socket..."); return -1; } -#else - TEST_CRITICAL("not implemented"); -#endif return 0; } diff --git a/test/main-server-http.cpp b/test/main-server-http.cpp index 812ebca..84b6682 100644 --- a/test/main-server-http.cpp +++ b/test/main-server-http.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -39,6 +40,7 @@ namespace appl { int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); + enet::init(_argc, _argv); for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if ( data == "-h" @@ -52,7 +54,6 @@ int main(int _argc, const char *_argv[]) { TEST_INFO("=================================="); TEST_INFO("== Test HTTP server =="); TEST_INFO("=================================="); -#ifndef __TARGET_OS__Windows //Wait on TCP connection: enet::TcpServer interface; // Configure server interface: @@ -112,8 +113,5 @@ int main(int _argc, const char *_argv[]) { } TEST_INFO("data : " << connection.dataString()); */ -#else - TEST_CRITICAL("not implemented"); -#endif return 0; } diff --git a/test/main-server-websocket.cpp b/test/main-server-websocket.cpp index ba3e6dd..f7e618f 100644 --- a/test/main-server-websocket.cpp +++ b/test/main-server-websocket.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -42,6 +43,7 @@ namespace appl { int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); + enet::init(_argc, _argv); for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if ( data == "-h" @@ -55,7 +57,6 @@ int main(int _argc, const char *_argv[]) { TEST_INFO("=================================="); TEST_INFO("== Test WebSocket server =="); TEST_INFO("=================================="); -#ifndef __TARGET_OS__Windows //Wait on TCP connection: enet::TcpServer interface; // Configure server interface: @@ -86,8 +87,5 @@ int main(int _argc, const char *_argv[]) { while (connection.isAlive() == true) { usleep(100000); } -#else - TEST_CRITICAL("not implemented"); -#endif return 0; } diff --git a/test/main-server.cpp b/test/main-server.cpp index 0619557..ca1b483 100644 --- a/test/main-server.cpp +++ b/test/main-server.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -14,6 +15,7 @@ int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); + enet::init(_argc, _argv); for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if ( data == "-h" @@ -27,12 +29,11 @@ int main(int _argc, const char *_argv[]) { TEST_INFO("=================================="); TEST_INFO("== Test TCP server =="); TEST_INFO("=================================="); -#ifndef __TARGET_OS__Windows //Wait on TCP connection: enet::TcpServer interface; // Configure server interface: interface.setHostNane("127.0.0.1"); - interface.setPort(31235); + interface.setPort(12345); // Start listening ... interface.link(); // Wait a new connection .. @@ -62,8 +63,5 @@ int main(int _argc, const char *_argv[]) { TEST_ERROR("can not unlink to the socket..."); return -1; } -#else - TEST_CRITICAL("not implemented"); -#endif return 0; }