[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_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<std::mutex> 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<std::mutex> 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<std::mutex> 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) {

View File

@ -10,8 +10,6 @@
#ifdef __TARGET_OS__Windows
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <poll.h>
#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();

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;
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) {

View File

@ -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;

View File

@ -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();
}

View File

@ -5,6 +5,7 @@
*/
#include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp>
#include <enet/TcpClient.hpp>
#include <enet/Http.hpp>
@ -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;
}

View File

@ -5,6 +5,7 @@
*/
#include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp>
#include <enet/TcpClient.hpp>
#include <enet/Http.hpp>
@ -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;
}

View File

@ -5,15 +5,17 @@
*/
#include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp>
#include <enet/TcpClient.hpp>
#include <enet/Http.hpp>
#include <etk/etk.hpp>
#include <iostream>
#include <etk/stdTools.hpp>
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;
}

View File

@ -5,6 +5,7 @@
*/
#include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp>
#include <enet/Http.hpp>
#include <enet/TcpServer.hpp>
@ -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;
}

View File

@ -5,6 +5,7 @@
*/
#include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp>
#include <enet/Http.hpp>
#include <enet/WebSocket.hpp>
@ -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;
}

View File

@ -5,6 +5,7 @@
*/
#include <test-debug/debug.hpp>
#include <enet/enet.hpp>
#include <enet/Tcp.hpp>
#include <enet/Http.hpp>
#include <etk/etk.hpp>
@ -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;
}