[DEV] try to stabilize interface TCP

This commit is contained in:
Edouard DUPIN 2017-04-27 21:47:42 +02:00
parent 63c9757a50
commit 36e7081920
3 changed files with 54 additions and 15 deletions

View File

@ -199,6 +199,19 @@ int32_t enet::Tcp::write(const void* _data, int32_t _len) {
ENET_ERROR("Can not write on unlink connection"); ENET_ERROR("Can not write on unlink connection");
return -1; return -1;
} }
if (_data == nullptr) {
ENET_ERROR("try write nullptr data on TCP socket");
return -1;
}
if (_len <= 0) {
if (_len == 0) {
ENET_WARNING("try write data with lenght=" << _len << " ==> bad case");
return 0;
}
ENET_ERROR("try write data with lenght=" << _len << " ==> bad case");
elog::displayBacktrace();
return -1;
}
//ENET_DEBUG("write on socketid = " << m_socketId << " data@=" << int64_t(_data) << " size=" << _len ); //ENET_DEBUG("write on socketid = " << m_socketId << " data@=" << int64_t(_data) << " size=" << _len );
int32_t size; int32_t size;
{ {

View File

@ -19,9 +19,11 @@
#else #else
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif #endif
enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry) { enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry, echrono::Duration _timeOut) {
std::string tmpname; std::string tmpname;
tmpname = etk::to_string(_ip1); tmpname = etk::to_string(_ip1);
tmpname += "."; tmpname += ".";
@ -30,23 +32,29 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
tmpname += etk::to_string(_ip3); tmpname += etk::to_string(_ip3);
tmpname += "."; tmpname += ".";
tmpname += etk::to_string(_ip4); tmpname += etk::to_string(_ip4);
return std::move(enet::connectTcpClient(tmpname, _port, _numberRetry)); return std::move(enet::connectTcpClient(tmpname, _port, _numberRetry, _timeOut));
} }
#ifdef __TARGET_OS__Windows #ifdef __TARGET_OS__Windows
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry) { enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry, echrono::Duration _timeOut) {
if (enet::isInit() == false) { if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket"); ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return std::move(enet::Tcp()); return std::move(enet::Tcp());
} }
if (_hostname == "") {
ENET_ERROR("get connection wihtout hostname");
return std::move(enet::Tcp());
}
SOCKET socketId = INVALID_SOCKET; SOCKET socketId = INVALID_SOCKET;
ENET_INFO("Start connection on " << _hostname << ":" << _port); ENET_INFO("Start connection on " << _hostname << ":" << _port);
for(int32_t iii=0; iii<_numberRetry ;iii++) { for(int32_t iii=0; iii<_numberRetry ;iii++) {
if (iii > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
// open in Socket normal mode // open in Socket normal mode
socketId = socket(AF_INET, SOCK_STREAM, 0); socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId < 0) { if (socketId < 0) {
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")"); ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")");
@ -63,7 +71,6 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
int iResult = getaddrinfo(_hostname.c_str(), portValue.c_str(), &hints, &result); int iResult = getaddrinfo(_hostname.c_str(), portValue.c_str(), &hints, &result);
if (iResult != 0) { if (iResult != 0) {
ENET_ERROR("getaddrinfo failed with error: " << iResult); ENET_ERROR("getaddrinfo failed with error: " << iResult);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
@ -92,7 +99,6 @@ 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!");
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} else { } else {
break; break;
@ -107,27 +113,48 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
} }
#else #else
#include <sys/socket.h> #include <sys/socket.h>
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry) { enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry, echrono::Duration _timeOut) {
if (enet::isInit() == false) { if (enet::isInit() == false) {
ENET_ERROR("Need call enet::init(...) before accessing to the socket"); ENET_ERROR("Need call enet::init(...) before accessing to the socket");
return std::move(enet::Tcp()); return std::move(enet::Tcp());
} }
if (_hostname == "") {
ENET_ERROR("get connection wihtout hostname");
return std::move(enet::Tcp());
}
int32_t socketId = -1; int32_t socketId = -1;
ENET_INFO("Start connection on " << _hostname << ":" << _port); ENET_INFO("Start connection on " << _hostname << ":" << _port);
for(int32_t iii=0; iii<_numberRetry ;iii++) { for(int32_t iii=0; iii<_numberRetry ;iii++) {
if (iii > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
// open in Socket normal mode // open in Socket normal mode
socketId = socket(AF_INET, SOCK_STREAM, 0); socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId < 0) { if (socketId < 0) {
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")"); ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")");
struct sockaddr_in servAddr; struct sockaddr_in servAddr;
struct hostent* server = gethostbyname(_hostname.c_str()); struct hostent* server = nullptr;
if (isalpha(_hostname.c_str()[0])) { /* host address is a name */
ENET_INFO("Calling gethostbyname with " << _hostname);
// TODO : This is deprecated use getaddrinfo like windows ...
server = gethostbyname(_hostname.c_str());
} else {
ENET_INFO("Calling gethostbyaddr with " << _hostname);
struct in_addr addr;
addr.s_addr = inet_addr(_hostname.c_str());
if (addr.s_addr == INADDR_NONE) {
ENET_ERROR("The IPv4 address entered must be a legal address" << _hostname.c_str());
return std::move(enet::Tcp());
} else {
// TODO : This is deprecated use getaddrinfo like windows ...
server = gethostbyaddr((char *) &addr, 4, AF_INET);
}
}
if (server == nullptr) { if (server == nullptr) {
ENET_ERROR("ERROR, no such host : " << _hostname); ENET_ERROR("ERROR, no such host : " << _hostname);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
bzero((char *) &servAddr, sizeof(servAddr)); bzero((char *) &servAddr, sizeof(servAddr));
@ -150,17 +177,15 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
socketId = -1; socketId = -1;
} }
ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno)); ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue; continue;
} }
// if we are here ==> then the connextion is done corectly ...
break; break;
} }
if (socketId<0) { if (socketId<0) {
ENET_ERROR("ERROR connecting ... (after all try)"); ENET_ERROR("ERROR connecting ... (after all try)");
return std::move(enet::Tcp()); return std::move(enet::Tcp());
} }
ENET_DEBUG("Connection done"); ENET_INFO("Connection done");
return std::move(enet::Tcp(socketId, _hostname + ":" + etk::to_string(_port))); return std::move(enet::Tcp(socketId, _hostname + ":" + etk::to_string(_port)));
} }
#endif #endif

View File

@ -6,8 +6,9 @@
#pragma once #pragma once
#include <enet/Tcp.hpp> #include <enet/Tcp.hpp>
#include <echrono/Duration.hpp>
namespace enet { namespace enet {
enet::Tcp connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry=5); enet::Tcp connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry=5, echrono::Duration _timeOut = echrono::seconds(1));
enet::Tcp connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry=5); enet::Tcp connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry=5, echrono::Duration _timeOut = echrono::seconds(1));
} }