[DEV] windows port functionnal and update Linux to support select on linux insated of poll

This commit is contained in:
Edouard DUPIN 2016-10-07 00:35:43 +02:00
parent a979e33401
commit 9e0421a822
11 changed files with 82 additions and 110 deletions

View File

@ -53,13 +53,7 @@ enet::Tcp::Tcp() :
m_socketId(_idSocket), m_socketId(_idSocket),
m_name(_name), m_name(_name),
m_status(status::link) { 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) : enet::Tcp::Tcp(Tcp&& _obj) :
@ -73,10 +67,6 @@ enet::Tcp::Tcp(Tcp&& _obj) :
#endif #endif
_obj.m_name = ""; _obj.m_name = "";
_obj.m_status = status::error; _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() { enet::Tcp::~Tcp() {
@ -95,10 +85,6 @@ enet::Tcp& enet::Tcp::operator = (enet::Tcp&& _obj) {
_obj.m_name = ""; _obj.m_name = "";
m_status = _obj.m_status; m_status = _obj.m_status;
_obj.m_status = status::error; _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; return *this;
} }
@ -107,16 +93,14 @@ bool enet::Tcp::unlink() {
ENET_INFO("Close socket (start)"); ENET_INFO("Close socket (start)");
#ifdef __TARGET_OS__Windows #ifdef __TARGET_OS__Windows
shutdown(m_socketId, SD_BOTH); shutdown(m_socketId, SD_BOTH);
closesocket(m_socketId);
m_socketId = INVALID_SOCKET;
#else #else
shutdown(m_socketId, SHUT_RDWR); shutdown(m_socketId, SHUT_RDWR);
#endif
#ifdef __TARGET_OS__Windows
closesocket(m_socketId);
#else
close(m_socketId); close(m_socketId);
m_socketId = -1;
#endif #endif
ENET_INFO("Close socket (done)"); ENET_INFO("Close socket (done)");
m_socketId = -1;
} }
m_status = status::unlink; m_status = status::unlink;
return true; return true;
@ -129,32 +113,36 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
return -1; return -1;
} }
int32_t size = -1; int32_t size = -1;
// 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 fd_set sock;
int nfds = 1; // Initialize the timeout to 3 minutes. If no activity after 3 minutes this program will end. timeout value is based on milliseconds.
// Call poll() and wait 3 minutes for it to complete. struct timeval timeOutStruct;
int rc = poll(m_fds, nfds, timeout); 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. // Check to see if the poll call failed.
if (rc < 0) { if (rc < 0) {
ENET_ERROR(" poll() failed"); ENET_ERROR(" select() failed");
return -1; return -1;
} }
// Check to see if the 3 minute time out expired. // Check to see if the 3 minute time out expired.
if (rc == 0) { if (rc == 0) {
ENET_ERROR(" poll() timed out.\n"); ENET_ERROR(" select() timed out.");
return -2; return -2;
} }
if (!FD_ISSET(m_socketId, &sock)) {
ENET_ERROR(" select() id is not set...");
return -1;
}
bool closeConn = false; bool closeConn = false;
// Receive all incoming data on this socket before we loop back and call poll again. // 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. // Receive data on this connection until the recv fails with EWOULDBLOCK.
// If any other failure occurs, we will close the connection. // If any other failure occurs, we will close the connection.
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
//ENET_DEBUG("Read on socketid = " << m_fds[0].fd ); rc = recv(m_socketId, (char *)_data, _maxLen, 0);
rc = recv(m_fds[0].fd, _data, _maxLen, 0);
} }
if (rc < 0) { if (rc < 0) {
if (errno != EWOULDBLOCK) { if (errno != EWOULDBLOCK) {
@ -176,7 +164,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
ENET_DEBUG(" Set status at remote close ..."); ENET_DEBUG(" Set status at remote close ...");
m_status = status::linkRemoteClose; m_status = status::linkRemoteClose;
} }
#endif //#endif
return size; return size;
} }
@ -190,11 +178,7 @@ int32_t enet::Tcp::write(const void* _data, int32_t _len) {
int32_t size; int32_t size;
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
#ifdef __TARGET_OS__Windows
size = ::send(m_socketId, (const char *)_data, _len, 0); size = ::send(m_socketId, (const char *)_data, _len, 0);
#else
size = ::write(m_socketId, _data, _len);
#endif
} }
if ( size != _len if ( size != _len
&& errno != 0) { && errno != 0) {

View File

@ -10,8 +10,6 @@
#ifdef __TARGET_OS__Windows #ifdef __TARGET_OS__Windows
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#else
#include <poll.h>
#endif #endif
namespace enet { namespace enet {
@ -22,11 +20,6 @@ namespace enet {
#else #else
int32_t m_socketId; //!< socket linux interface generic int32_t m_socketId; //!< socket linux interface generic
#endif #endif
#ifdef __TARGET_OS__Windows
int32_t m_fds[1];
#else
struct pollfd m_fds[1];
#endif
std::mutex m_mutex; std::mutex m_mutex;
public: public:
Tcp(); Tcp();

View File

@ -71,6 +71,7 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
for(struct addrinfo* ptr=result; for(struct addrinfo* ptr=result;
ptr != nullptr; ptr != nullptr;
ptr=ptr->ai_next) { ptr=ptr->ai_next) {
ENET_DEBUG(" find one ...");
// Create a SOCKET for connecting to server // Create a SOCKET for connecting to server
socketId = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); socketId = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (socketId == INVALID_SOCKET) { 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. // Connect to server.
iResult = connect(socketId, ptr->ai_addr, (int)ptr->ai_addrlen); iResult = connect(socketId, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) { if (iResult == SOCKET_ERROR) {
ENET_ERROR("socket connection failed with error: " << WSAGetLastError());
closesocket(socketId); closesocket(socketId);
socketId = INVALID_SOCKET; socketId = INVALID_SOCKET;
continue; continue;
@ -90,9 +92,10 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
if (socketId == INVALID_SOCKET) { if (socketId == INVALID_SOCKET) {
ENET_ERROR("Unable to connect to server!"); ENET_ERROR("Unable to connect to server!");
WSACleanup();
usleep(200000); usleep(200000);
continue; continue;
} else {
break;
} }
} }
if (socketId == INVALID_SOCKET) { if (socketId == INVALID_SOCKET) {

View File

@ -88,7 +88,7 @@ void enet::TcpServer::setPort(uint16_t _port) {
// open in Socket normal mode // open in Socket normal mode
m_socketId = socket(result->ai_family, result->ai_socktype, result->ai_protocol); 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)); ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
freeaddrinfo(result); freeaddrinfo(result);
return false; return false;

View File

@ -36,7 +36,7 @@ void enet::init(int _argc, const char** _argv) {
} }
} }
void unInit() { void enet::unInit() {
if (getInitSatatus() == false) { if (getInitSatatus() == false) {
ENET_ERROR("Request UnInit of enent already done ..."); ENET_ERROR("Request UnInit of enent already done ...");
} else { } else {
@ -48,7 +48,7 @@ void unInit() {
} }
bool isInit() { bool enet::isInit() {
return getInitSatatus(); return getInitSatatus();
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <enet/TcpClient.hpp> #include <enet/TcpClient.hpp>
#include <enet/Http.hpp> #include <enet/Http.hpp>
@ -22,6 +23,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@ -35,7 +37,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test HTTP client =="); TEST_INFO("== Test HTTP client ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
// connect on TCP server: // connect on TCP server:
enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345));
// TODO : Check if connection is valid ... // 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 ...) // start http connection (the actual state is just TCP start ...)
connection.start(); connection.start();
enet::HttpRequest req(enet::HTTPReqType::GET); enet::HttpRequest req(enet::HTTPReqType::HTTP_GET);
req.setUri("plop.txt"); req.setUri("plop.txt");
connection.setHeader(req); connection.setHeader(req);
while (connection.isAlive() == true) { while (connection.isAlive() == true) {
usleep(100000); usleep(100000);
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <enet/TcpClient.hpp> #include <enet/TcpClient.hpp>
#include <enet/Http.hpp> #include <enet/Http.hpp>
@ -29,6 +30,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@ -42,7 +44,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test WebSocket client =="); TEST_INFO("== Test WebSocket client ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
// connect on TCP server: // connect on TCP server:
enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); enet::Tcp tcpConnection = std::move(enet::connectTcpClient("127.0.0.1", 12345));
// TODO : Check if connection is valid ... // TODO : Check if connection is valid ...
@ -68,9 +69,5 @@ int main(int _argc, const char *_argv[]) {
usleep(100000); usleep(100000);
timeout--; timeout--;
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@ -5,15 +5,17 @@
*/ */
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <enet/TcpClient.hpp> #include <enet/TcpClient.hpp>
#include <enet/Http.hpp> #include <enet/Http.hpp>
#include <etk/etk.hpp> #include <etk/etk.hpp>
#include <iostream>
#include <etk/stdTools.hpp> #include <etk/stdTools.hpp>
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@ -27,7 +29,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test TCP client =="); TEST_INFO("== Test TCP client ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
// client mode ... // client mode ...
// connect on TCP server: // connect on TCP server:
enet::Tcp connection = std::move(enet::connectTcpClient("127.0.0.1", 12345)); 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; return -1;
} }
int32_t iii = 0; int32_t iii = 0;
int32_t delay = 200;
while ( connection.getConnectionStatus() == enet::Tcp::status::link while ( connection.getConnectionStatus() == enet::Tcp::status::link
&& iii<10000) { && iii<10000) {
char data[1024]; char data[1024];
int32_t len = connection.read(data, 1024); int32_t len = connection.read(data, 1024);
TEST_INFO("read len=" << len << " data='" << data << "'"); TEST_INFO("read len=" << len << " data='" << data << "'");
//if (data[len-1] == '2') { //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"); int32_t lenWrite = connection.write("get pair value");
TEST_INFO("write len=" << lenWrite); TEST_INFO("write len=" << lenWrite);
//} //}
@ -59,8 +66,5 @@ int main(int _argc, const char *_argv[]) {
TEST_ERROR("can not unlink to the socket..."); TEST_ERROR("can not unlink to the socket...");
return -1; return -1;
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <enet/Http.hpp> #include <enet/Http.hpp>
#include <enet/TcpServer.hpp> #include <enet/TcpServer.hpp>
@ -39,6 +40,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@ -52,7 +54,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test HTTP server =="); TEST_INFO("== Test HTTP server ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
//Wait on TCP connection: //Wait on TCP connection:
enet::TcpServer interface; enet::TcpServer interface;
// Configure server interface: // Configure server interface:
@ -112,8 +113,5 @@ int main(int _argc, const char *_argv[]) {
} }
TEST_INFO("data : " << connection.dataString()); TEST_INFO("data : " << connection.dataString());
*/ */
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <enet/Http.hpp> #include <enet/Http.hpp>
#include <enet/WebSocket.hpp> #include <enet/WebSocket.hpp>
@ -42,6 +43,7 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@ -55,7 +57,6 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test WebSocket server =="); TEST_INFO("== Test WebSocket server ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
//Wait on TCP connection: //Wait on TCP connection:
enet::TcpServer interface; enet::TcpServer interface;
// Configure server interface: // Configure server interface:
@ -86,8 +87,5 @@ int main(int _argc, const char *_argv[]) {
while (connection.isAlive() == true) { while (connection.isAlive() == true) {
usleep(100000); usleep(100000);
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <enet/Http.hpp> #include <enet/Http.hpp>
#include <etk/etk.hpp> #include <etk/etk.hpp>
@ -14,6 +15,7 @@
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
enet::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if ( data == "-h" if ( data == "-h"
@ -27,12 +29,11 @@ int main(int _argc, const char *_argv[]) {
TEST_INFO("=================================="); TEST_INFO("==================================");
TEST_INFO("== Test TCP server =="); TEST_INFO("== Test TCP server ==");
TEST_INFO("=================================="); TEST_INFO("==================================");
#ifndef __TARGET_OS__Windows
//Wait on TCP connection: //Wait on TCP connection:
enet::TcpServer interface; enet::TcpServer interface;
// Configure server interface: // Configure server interface:
interface.setHostNane("127.0.0.1"); interface.setHostNane("127.0.0.1");
interface.setPort(31235); interface.setPort(12345);
// Start listening ... // Start listening ...
interface.link(); interface.link();
// Wait a new connection .. // Wait a new connection ..
@ -62,8 +63,5 @@ int main(int _argc, const char *_argv[]) {
TEST_ERROR("can not unlink to the socket..."); TEST_ERROR("can not unlink to the socket...");
return -1; return -1;
} }
#else
TEST_CRITICAL("not implemented");
#endif
return 0; return 0;
} }