[DEV] new interface of server connection ==> start to work (remove http)
This commit is contained in:
parent
96abe77af6
commit
fe937bbe64
@ -9,7 +9,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <etk/stdTools.h>
|
#include <etk/stdTools.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#if 0
|
||||||
static std::map<int32_t, std::string> getErrorList() {
|
static std::map<int32_t, std::string> getErrorList() {
|
||||||
static std::map<int32_t, std::string> g_list;
|
static std::map<int32_t, std::string> g_list;
|
||||||
return g_list;
|
return g_list;
|
||||||
@ -302,3 +302,5 @@ std::string enet::Http::dataString() {
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#if 0
|
||||||
namespace enet {
|
namespace enet {
|
||||||
class Http {
|
class Http {
|
||||||
public:
|
public:
|
||||||
@ -55,4 +55,4 @@ namespace enet {
|
|||||||
bool receiveData();
|
bool receiveData();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
218
enet/Tcp.cpp
218
enet/Tcp.cpp
@ -18,178 +18,58 @@
|
|||||||
|
|
||||||
enet::Tcp::Tcp() :
|
enet::Tcp::Tcp() :
|
||||||
m_socketId(-1),
|
m_socketId(-1),
|
||||||
m_socketIdClient(-1),
|
m_name(),
|
||||||
m_host("127.0.0.1"),
|
m_status(status::error) {
|
||||||
m_port(23191),
|
|
||||||
m_server(false),
|
|
||||||
m_status(status::unlink) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enet::Tcp::~Tcp() {
|
enet::Tcp::Tcp(int32_t _idSocket, const std::string& _name) :
|
||||||
unlink();
|
m_socketId(_idSocket),
|
||||||
}
|
m_name(_name),
|
||||||
|
m_status(status::link) {
|
||||||
void enet::Tcp::setIpV4(uint8_t _fist, uint8_t _second, uint8_t _third, uint8_t _quatro) {
|
|
||||||
std::string tmpname;
|
|
||||||
tmpname = etk::to_string(_fist);
|
|
||||||
tmpname += ".";
|
|
||||||
tmpname += etk::to_string(_second);
|
|
||||||
tmpname += ".";
|
|
||||||
tmpname += etk::to_string(_third);
|
|
||||||
tmpname += ".";
|
|
||||||
tmpname += etk::to_string(_quatro);
|
|
||||||
setHostNane(tmpname);
|
|
||||||
}
|
|
||||||
|
|
||||||
void enet::Tcp::setHostNane(const std::string& _name) {
|
|
||||||
if (_name == m_host) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_status == status::link) {
|
|
||||||
ENET_ERROR("Can not change parameter while connection is started");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_host = _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void enet::Tcp::setPort(uint16_t _port) {
|
|
||||||
if (_port == m_port) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_status == status::link) {
|
|
||||||
ENET_ERROR("Can not change parameter while connection is started");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_port = _port;
|
|
||||||
}
|
|
||||||
|
|
||||||
void enet::Tcp::setServer(bool _status) {
|
|
||||||
if (_status == m_server) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_status == status::link) {
|
|
||||||
ENET_ERROR("Can not change parameter while connection is started");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_server = _status;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enet::Tcp::link() {
|
|
||||||
if (m_status == status::link) {
|
|
||||||
ENET_ERROR("Connection is already started");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ENET_INFO("Start connection on " << m_host << ":" << m_port);
|
|
||||||
if (m_server == false) {
|
|
||||||
#define MAX_TEST_TIME (5)
|
|
||||||
for(int32_t iii=0; iii<MAX_TEST_TIME ;iii++) {
|
|
||||||
// open in Socket normal mode
|
|
||||||
m_socketIdClient = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (m_socketIdClient < 0) {
|
|
||||||
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
|
|
||||||
usleep(200000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << MAX_TEST_TIME << ")");
|
|
||||||
struct sockaddr_in servAddr;
|
|
||||||
struct hostent* server = gethostbyname(m_host.c_str());
|
|
||||||
if (server == NULL) {
|
|
||||||
ENET_ERROR("ERROR, no such host : " << m_host);
|
|
||||||
usleep(200000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bzero((char *) &servAddr, sizeof(servAddr));
|
|
||||||
servAddr.sin_family = AF_INET;
|
|
||||||
bcopy((char *)server->h_addr, (char *)&servAddr.sin_addr.s_addr, server->h_length);
|
|
||||||
servAddr.sin_port = htons(m_port);
|
|
||||||
ENET_INFO("Start connexion ...");
|
|
||||||
if (connect(m_socketIdClient, (struct sockaddr *)&servAddr,sizeof(servAddr)) != 0) {
|
|
||||||
if(errno != EINPROGRESS) {
|
|
||||||
if( errno != ENOENT
|
|
||||||
&& errno != EAGAIN
|
|
||||||
&& errno != ECONNREFUSED) {
|
|
||||||
ENET_ERROR("ERROR connecting on : errno=" << errno << "," << strerror(errno));
|
|
||||||
}
|
|
||||||
close(m_socketIdClient);
|
|
||||||
m_socketIdClient = -1;
|
|
||||||
}
|
|
||||||
ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno));
|
|
||||||
usleep(500000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// if we are here ==> then the connextion is done corectly ...
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (m_socketIdClient<0) {
|
|
||||||
ENET_ERROR("ERROR connecting ... (after all try)");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
m_status = status::link;
|
|
||||||
ENET_DEBUG("Connection done");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// open in Socket normal mode
|
|
||||||
m_socketId = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (m_socketId < 0) {
|
|
||||||
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// set the reuse of the socket if previously opened :
|
|
||||||
int sockOpt = 1;
|
|
||||||
if(setsockopt(m_socketId, SOL_SOCKET, SO_REUSEADDR, (const char*)&sockOpt, sizeof(int)) != 0) {
|
|
||||||
ENET_ERROR("ERROR while configuring socket re-use : errno=" << errno << "," << strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// clear all
|
|
||||||
struct sockaddr_in servAddr;
|
|
||||||
bzero((char *) &servAddr, sizeof(servAddr));
|
|
||||||
servAddr.sin_family = AF_INET;
|
|
||||||
servAddr.sin_addr.s_addr = INADDR_ANY;
|
|
||||||
servAddr.sin_port = htons(m_port);
|
|
||||||
ENET_INFO("Start binding Socket ... (can take some time ...)");
|
|
||||||
if (bind(m_socketId, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
|
|
||||||
ENET_ERROR("ERROR on binding errno=" << errno << "," << strerror(errno));
|
|
||||||
close(m_socketId);
|
|
||||||
m_socketId = -1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ENET_INFO("End binding Socket ... (start listen)");
|
|
||||||
listen(m_socketId,1); // 1 is for the number of connection at the same time ...
|
|
||||||
ENET_INFO("End listen Socket ... (start accept)");
|
|
||||||
struct sockaddr_in clientAddr;
|
|
||||||
socklen_t clilen = sizeof(clientAddr);
|
|
||||||
m_socketIdClient = accept(m_socketId, (struct sockaddr *) &clientAddr, &clilen);
|
|
||||||
if (m_socketIdClient < 0) {
|
|
||||||
ENET_ERROR("ERROR on accept errno=" << errno << "," << strerror(errno));
|
|
||||||
close(m_socketId);
|
|
||||||
m_socketId = -1;
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
m_status = status::link;
|
|
||||||
ENET_DEBUG("Connection done");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 1
|
#if 1
|
||||||
//Initialize the pollfd structure
|
//Initialize the pollfd structure
|
||||||
memset(m_fds, 0 , sizeof(m_fds));
|
memset(m_fds, 0 , sizeof(m_fds));
|
||||||
//Set up the initial listening socket
|
//Set up the initial listening socket
|
||||||
m_fds[0].fd = m_socketIdClient;
|
m_fds[0].fd = _idSocket;
|
||||||
m_fds[0].events = POLLIN | POLLERR;
|
m_fds[0].events = POLLIN | POLLERR;
|
||||||
#endif
|
#endif
|
||||||
ENET_INFO("End configuring Socket ...");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enet::Tcp::Tcp(Tcp&& _obj) :
|
||||||
|
m_socketId(_obj.m_socketId),
|
||||||
|
m_name(_obj.m_name),
|
||||||
|
m_status(_obj.m_status) {
|
||||||
|
_obj.m_socketId = -1;
|
||||||
|
_obj.m_name = "";
|
||||||
|
_obj.m_status = status::error;
|
||||||
|
m_fds[0] = _obj.m_fds[0];
|
||||||
|
#if 1
|
||||||
|
memset(_obj.m_fds, 0 , sizeof(_obj.m_fds));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
enet::Tcp::~Tcp() {
|
||||||
|
unlink();
|
||||||
|
}
|
||||||
|
|
||||||
|
enet::Tcp& enet::Tcp::operator = (enet::Tcp&& _obj) {
|
||||||
|
unlink();
|
||||||
|
m_socketId = _obj.m_socketId;
|
||||||
|
_obj.m_socketId = -1;
|
||||||
|
m_name = _obj.m_name;
|
||||||
|
_obj.m_name = "";
|
||||||
|
m_status = _obj.m_status;
|
||||||
|
_obj.m_status = status::error;
|
||||||
|
m_fds[0] = _obj.m_fds[0];
|
||||||
|
#if 1
|
||||||
|
memset(_obj.m_fds, 0 , sizeof(_obj.m_fds));
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool enet::Tcp::unlink() {
|
bool enet::Tcp::unlink() {
|
||||||
if (m_socketIdClient >= 0) {
|
|
||||||
ENET_INFO(" close client socket");
|
|
||||||
close(m_socketIdClient);
|
|
||||||
m_socketIdClient = -1;
|
|
||||||
}
|
|
||||||
if (m_socketId >= 0) {
|
if (m_socketId >= 0) {
|
||||||
ENET_INFO(" close server socket");
|
ENET_INFO("Close socket");
|
||||||
close(m_socketId);
|
close(m_socketId);
|
||||||
m_socketId = -1;
|
m_socketId = -1;
|
||||||
}
|
}
|
||||||
@ -206,7 +86,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
|||||||
}
|
}
|
||||||
int32_t size = -1;
|
int32_t size = -1;
|
||||||
#if 0
|
#if 0
|
||||||
size = ::read(m_socketIdClient, _data, _maxLen);
|
size = ::read(m_socketId, _data, _maxLen);
|
||||||
if ( size != 0
|
if ( size != 0
|
||||||
&& errno == 2) {
|
&& errno == 2) {
|
||||||
// simply the socket en empty
|
// simply the socket en empty
|
||||||
@ -307,7 +187,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
|||||||
if (new_sd < 0) {
|
if (new_sd < 0) {
|
||||||
if (errno != EWOULDBLOCK) {
|
if (errno != EWOULDBLOCK) {
|
||||||
ENET_ERROR(" accept() failed");
|
ENET_ERROR(" accept() failed");
|
||||||
end_server = TRUE;
|
end_server = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -321,7 +201,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
|||||||
} else {
|
} else {
|
||||||
// This is not the listening socket, therefore an existing connection must be readable
|
// This is not the listening socket, therefore an existing connection must be readable
|
||||||
ENET_INFO(" Descriptor %d is readable", fds[iii].fd);
|
ENET_INFO(" Descriptor %d is readable", fds[iii].fd);
|
||||||
close_conn = FALSE;
|
close_conn = 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.
|
||||||
do {
|
do {
|
||||||
// Receive data on this connection until the recv fails with EWOULDBLOCK.
|
// Receive data on this connection until the recv fails with EWOULDBLOCK.
|
||||||
@ -330,14 +210,14 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
|||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
if (errno != EWOULDBLOCK) {
|
if (errno != EWOULDBLOCK) {
|
||||||
perror(" recv() failed");
|
perror(" recv() failed");
|
||||||
close_conn = TRUE;
|
close_conn = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Check to see if the connection has been closed by the client
|
// Check to see if the connection has been closed by the client
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
ENET_ERROR(" Connection closed");
|
ENET_ERROR(" Connection closed");
|
||||||
close_conn = TRUE;
|
close_conn = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Data was received
|
// Data was received
|
||||||
@ -347,23 +227,23 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
|||||||
rc = send(m_fds[i].fd, buffer, len, 0);
|
rc = send(m_fds[i].fd, buffer, len, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
ENET_ERRO(" send() failed");
|
ENET_ERRO(" send() failed");
|
||||||
close_conn = TRUE;
|
close_conn = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while(TRUE);
|
} while(true);
|
||||||
// If the close_conn flag was turned on, we need to clean up this active connection.
|
// If the close_conn flag was turned on, we need to clean up this active connection.
|
||||||
// This clean up process includes removing the descriptor.
|
// This clean up process includes removing the descriptor.
|
||||||
if (close_conn) {
|
if (close_conn) {
|
||||||
close(m_fds[i].fd);
|
close(m_fds[i].fd);
|
||||||
m_fds[i].fd = -1;
|
m_fds[i].fd = -1;
|
||||||
compress_array = TRUE;
|
compress_array = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the compress_array flag was turned on, we need to squeeze together the array and decrement the number of file descriptors.
|
// If the compress_array flag was turned on, we need to squeeze together the array and decrement the number of file descriptors.
|
||||||
// We do not need to move back the events and revents fields because the events will always be POLLIN in this case, and revents is output.
|
// We do not need to move back the events and revents fields because the events will always be POLLIN in this case, and revents is output.
|
||||||
if (compress_array) {
|
if (compress_array) {
|
||||||
compress_array = FALSE;
|
compress_array = false;
|
||||||
for (int32_t iii=0; iii<nfds; ++iii) {
|
for (int32_t iii=0; iii<nfds; ++iii) {
|
||||||
if (m_fds[i].fd == -1) {
|
if (m_fds[i].fd == -1) {
|
||||||
for(int32_t jjj = iii; jjj < nfds; ++jjj) {
|
for(int32_t jjj = iii; jjj < nfds; ++jjj) {
|
||||||
@ -373,7 +253,7 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (end_server == FALSE);
|
} while (end_server == false);
|
||||||
// Clean up all of the sockets that are open
|
// Clean up all of the sockets that are open
|
||||||
for (int32_t iii=0; iii<nfds; ++iii) {
|
for (int32_t iii=0; iii<nfds; ++iii) {
|
||||||
if(m_fds[iii].fd >= 0) {
|
if(m_fds[iii].fd >= 0) {
|
||||||
@ -392,7 +272,7 @@ 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;
|
||||||
}
|
}
|
||||||
int32_t size = ::write(m_socketIdClient, _data, _len);
|
int32_t size = ::write(m_socketId, _data, _len);
|
||||||
if ( size != _len
|
if ( size != _len
|
||||||
&& errno != 0) {
|
&& errno != 0) {
|
||||||
ENET_ERROR("PB when writing data on the FD : request=" << _len << " have=" << size << ", erno=" << errno << "," << strerror(errno));
|
ENET_ERROR("PB when writing data on the FD : request=" << _len << " have=" << size << ", erno=" << errno << "," << strerror(errno));
|
||||||
|
66
enet/Tcp.h
66
enet/Tcp.h
@ -5,71 +5,35 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
namespace enet {
|
namespace enet {
|
||||||
class Tcp {
|
class Tcp {
|
||||||
private:
|
private:
|
||||||
int32_t m_socketId; //!< socket linux interface generic
|
int32_t m_socketId; //!< socket linux interface generic
|
||||||
int32_t m_socketIdClient;
|
|
||||||
#if 1
|
#if 1
|
||||||
struct pollfd m_fds[1];
|
struct pollfd m_fds[1];
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
Tcp();
|
Tcp();
|
||||||
|
Tcp(int32_t _idSocket, const std::string& _name);
|
||||||
|
// move constructor
|
||||||
|
Tcp(Tcp&& _obj);
|
||||||
|
// Move operator;
|
||||||
|
Tcp& operator= (Tcp&& _obj);
|
||||||
|
// Remove copy operator ... ==> not valid ...
|
||||||
|
Tcp& operator= (Tcp& _obj) = delete;
|
||||||
virtual ~Tcp();
|
virtual ~Tcp();
|
||||||
private:
|
private:
|
||||||
std::string m_host; //!< hostname/IP to connect with.
|
std::string m_name; //!< hostname/IP:port.
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Set the connection IP id.
|
* @brief Get the decriptive name hot the host:port
|
||||||
* @param[in] _first Firt number of the IP v4.
|
|
||||||
* @param[in] _second Second number of the IP v4.
|
|
||||||
* @param[in] _third Third number of the IP v4.
|
|
||||||
* @param[in] _quatro Quatro number of the IP v4.
|
|
||||||
*/
|
|
||||||
void setIpV4(uint8_t _fist, uint8_t _second, uint8_t _third, uint8_t _quatro);
|
|
||||||
/**
|
|
||||||
* @brief set the Host name is the same things as set an Ip adress, but in test mode "127.0.0.1" or "localhost".
|
|
||||||
* @param[in] _name Host name to connect.
|
|
||||||
*/
|
|
||||||
void setHostNane(const std::string& _name);
|
|
||||||
/**
|
|
||||||
* @brief Get the decriptive name hot the host
|
|
||||||
* @return the string requested
|
* @return the string requested
|
||||||
*/
|
*/
|
||||||
const std::string& getHostName() {
|
const std::string& getName() {
|
||||||
return m_host;
|
return m_name;
|
||||||
}
|
|
||||||
private:
|
|
||||||
uint16_t m_port; //!< IP port to connect with.
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief set the port number to connect or to spy
|
|
||||||
* @param[in] _port Number of the port requested
|
|
||||||
*/
|
|
||||||
void setPort(uint16_t _port);
|
|
||||||
/**
|
|
||||||
* @brief Get the port number.
|
|
||||||
* @return The requested port number.
|
|
||||||
*/
|
|
||||||
uint16_t getPort() {
|
|
||||||
return m_port;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
bool m_server; //!< if at true, the server mode is requested
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Set the TCP interface in server mode
|
|
||||||
* @param[in] _status if true, this enable the server mode
|
|
||||||
*/
|
|
||||||
void setServer(bool _status);
|
|
||||||
/**
|
|
||||||
* @brief Get the server mode status.
|
|
||||||
* @return true: the tcp interface is configure as a server.
|
|
||||||
*/
|
|
||||||
int32_t getServer() {
|
|
||||||
return m_server;
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
enum class status {
|
enum class status {
|
||||||
@ -89,12 +53,6 @@ namespace enet {
|
|||||||
return m_status;
|
return m_status;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* @brief Link on a specific interface.
|
|
||||||
* @return true if connection is done
|
|
||||||
* @return false otherwise ...
|
|
||||||
*/
|
|
||||||
bool link();
|
|
||||||
/**
|
/**
|
||||||
* @brief Unlink on a specific interface.
|
* @brief Unlink on a specific interface.
|
||||||
* @return true if connection is removed
|
* @return true if connection is removed
|
||||||
|
79
enet/TcpClient.cpp
Normal file
79
enet/TcpClient.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <enet/debug.h>
|
||||||
|
#include <enet/Tcp.h>
|
||||||
|
#include <enet/TcpClient.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <etk/stdTools.h>
|
||||||
|
|
||||||
|
enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port) {
|
||||||
|
std::string tmpname;
|
||||||
|
tmpname = etk::to_string(_ip1);
|
||||||
|
tmpname += ".";
|
||||||
|
tmpname += etk::to_string(_ip2);
|
||||||
|
tmpname += ".";
|
||||||
|
tmpname += etk::to_string(_ip3);
|
||||||
|
tmpname += ".";
|
||||||
|
tmpname += etk::to_string(_ip4);
|
||||||
|
return std::move(enet::connectTcpClient(tmpname, _port));
|
||||||
|
}
|
||||||
|
#define MAX_TEST_TIME (50)
|
||||||
|
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port) {
|
||||||
|
int32_t socketId = -1;
|
||||||
|
ENET_INFO("Start connection on " << _hostname << ":" << _port);
|
||||||
|
for(int32_t iii=0; iii<MAX_TEST_TIME ;iii++) {
|
||||||
|
// open in Socket normal mode
|
||||||
|
socketId = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (socketId < 0) {
|
||||||
|
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
|
||||||
|
usleep(200000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << MAX_TEST_TIME << ")");
|
||||||
|
struct sockaddr_in servAddr;
|
||||||
|
struct hostent* server = gethostbyname(_hostname.c_str());
|
||||||
|
if (server == nullptr) {
|
||||||
|
ENET_ERROR("ERROR, no such host : " << _hostname);
|
||||||
|
usleep(200000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bzero((char *) &servAddr, sizeof(servAddr));
|
||||||
|
servAddr.sin_family = AF_INET;
|
||||||
|
bcopy((char *)server->h_addr, (char *)&servAddr.sin_addr.s_addr, server->h_length);
|
||||||
|
servAddr.sin_port = htons(_port);
|
||||||
|
ENET_INFO("Start connexion ...");
|
||||||
|
if (connect(socketId, (struct sockaddr *)&servAddr,sizeof(servAddr)) != 0) {
|
||||||
|
if(errno != EINPROGRESS) {
|
||||||
|
if( errno != ENOENT
|
||||||
|
&& errno != EAGAIN
|
||||||
|
&& errno != ECONNREFUSED) {
|
||||||
|
ENET_ERROR("ERROR connecting on : errno=" << errno << "," << strerror(errno));
|
||||||
|
}
|
||||||
|
close(socketId);
|
||||||
|
socketId = -1;
|
||||||
|
}
|
||||||
|
ENET_ERROR("ERROR connecting, maybe retry ... errno=" << errno << "," << strerror(errno));
|
||||||
|
usleep(500000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// if we are here ==> then the connextion is done corectly ...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (socketId<0) {
|
||||||
|
ENET_ERROR("ERROR connecting ... (after all try)");
|
||||||
|
return std::move(enet::Tcp());
|
||||||
|
}
|
||||||
|
ENET_DEBUG("Connection done");
|
||||||
|
return std::move(enet::Tcp(socketId, _hostname + ":" + etk::to_string(_port)));
|
||||||
|
}
|
||||||
|
|
13
enet/TcpClient.h
Normal file
13
enet/TcpClient.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <enet/Tcp.h>
|
||||||
|
|
||||||
|
namespace enet {
|
||||||
|
enet::Tcp connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port);
|
||||||
|
enet::Tcp connectTcpClient(const std::string& _hostname, uint16_t _port);
|
||||||
|
}
|
112
enet/TcpServer.cpp
Normal file
112
enet/TcpServer.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <enet/debug.h>
|
||||||
|
#include <enet/Tcp.h>
|
||||||
|
#include <enet/TcpServer.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <etk/stdTools.h>
|
||||||
|
|
||||||
|
|
||||||
|
enet::TcpServer::TcpServer() :
|
||||||
|
m_socketId(-1),
|
||||||
|
m_host("127.0.0.1"),
|
||||||
|
m_port(23191) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
enet::TcpServer::~TcpServer() {
|
||||||
|
unlink();
|
||||||
|
}
|
||||||
|
|
||||||
|
void enet::TcpServer::setIpV4(uint8_t _fist, uint8_t _second, uint8_t _third, uint8_t _quatro) {
|
||||||
|
std::string tmpname;
|
||||||
|
tmpname = etk::to_string(_fist);
|
||||||
|
tmpname += ".";
|
||||||
|
tmpname += etk::to_string(_second);
|
||||||
|
tmpname += ".";
|
||||||
|
tmpname += etk::to_string(_third);
|
||||||
|
tmpname += ".";
|
||||||
|
tmpname += etk::to_string(_quatro);
|
||||||
|
setHostNane(tmpname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enet::TcpServer::setHostNane(const std::string& _name) {
|
||||||
|
if (_name == m_host) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_host = _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enet::TcpServer::setPort(uint16_t _port) {
|
||||||
|
if (_port == m_port) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_port = _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enet::TcpServer::link() {
|
||||||
|
ENET_INFO("Start connection on " << m_host << ":" << m_port);
|
||||||
|
// open in Socket normal mode
|
||||||
|
m_socketId = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (m_socketId < 0) {
|
||||||
|
ENET_ERROR("ERROR while opening socket : errno=" << errno << "," << strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// set the reuse of the socket if previously opened :
|
||||||
|
int sockOpt = 1;
|
||||||
|
if(setsockopt(m_socketId, SOL_SOCKET, SO_REUSEADDR, (const char*)&sockOpt, sizeof(int)) != 0) {
|
||||||
|
ENET_ERROR("ERROR while configuring socket re-use : errno=" << errno << "," << strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// clear all
|
||||||
|
struct sockaddr_in servAddr;
|
||||||
|
bzero((char *) &servAddr, sizeof(servAddr));
|
||||||
|
servAddr.sin_family = AF_INET;
|
||||||
|
servAddr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
servAddr.sin_port = htons(m_port);
|
||||||
|
ENET_INFO("Start binding Socket ... (can take some time ...)");
|
||||||
|
if (bind(m_socketId, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
|
||||||
|
ENET_ERROR("ERROR on binding errno=" << errno << "," << strerror(errno));
|
||||||
|
close(m_socketId);
|
||||||
|
m_socketId = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enet::Tcp enet::TcpServer::waitNext() {
|
||||||
|
ENET_INFO("End binding Socket ... (start listen)");
|
||||||
|
listen(m_socketId,1); // 1 is for the number of connection at the same time ...
|
||||||
|
ENET_INFO("End listen Socket ... (start accept)");
|
||||||
|
struct sockaddr_in clientAddr;
|
||||||
|
socklen_t clilen = sizeof(clientAddr);
|
||||||
|
int32_t socketIdClient = accept(m_socketId, (struct sockaddr *) &clientAddr, &clilen);
|
||||||
|
if (socketIdClient < 0) {
|
||||||
|
ENET_ERROR("ERROR on accept errno=" << errno << "," << strerror(errno));
|
||||||
|
close(m_socketId);
|
||||||
|
m_socketId = -1;
|
||||||
|
return enet::Tcp();
|
||||||
|
}
|
||||||
|
ENET_INFO("End configuring Socket ... Find New one");
|
||||||
|
return enet::Tcp(socketIdClient, m_host + ":" + etk::to_string(m_port));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool enet::TcpServer::unlink() {
|
||||||
|
if (m_socketId >= 0) {
|
||||||
|
ENET_INFO(" close server socket");
|
||||||
|
close(m_socketId);
|
||||||
|
m_socketId = -1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
69
enet/TcpServer.h
Normal file
69
enet/TcpServer.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
#include <enet/Tcp.h>
|
||||||
|
|
||||||
|
namespace enet {
|
||||||
|
class TcpServer {
|
||||||
|
private:
|
||||||
|
int32_t m_socketId; //!< socket linux interface generic
|
||||||
|
#if 1
|
||||||
|
struct pollfd m_fds[1];
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
TcpServer();
|
||||||
|
virtual ~TcpServer();
|
||||||
|
private:
|
||||||
|
std::string m_host; //!< hostname/IP to connect with.
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Set the connection IP id.
|
||||||
|
* @param[in] _first Firt number of the IP v4.
|
||||||
|
* @param[in] _second Second number of the IP v4.
|
||||||
|
* @param[in] _third Third number of the IP v4.
|
||||||
|
* @param[in] _quatro Quatro number of the IP v4.
|
||||||
|
*/
|
||||||
|
void setIpV4(uint8_t _fist, uint8_t _second, uint8_t _third, uint8_t _quatro);
|
||||||
|
/**
|
||||||
|
* @brief set the Host name is the same things as set an Ip adress, but in test mode "127.0.0.1" or "localhost".
|
||||||
|
* @param[in] _name Host name to connect.
|
||||||
|
*/
|
||||||
|
void setHostNane(const std::string& _name);
|
||||||
|
/**
|
||||||
|
* @brief Get the decriptive name hot the host
|
||||||
|
* @return the string requested
|
||||||
|
*/
|
||||||
|
const std::string& getHostName() {
|
||||||
|
return m_host;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint16_t m_port; //!< IP port to connect with.
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief set the port number to connect or to spy
|
||||||
|
* @param[in] _port Number of the port requested
|
||||||
|
*/
|
||||||
|
void setPort(uint16_t _port);
|
||||||
|
/**
|
||||||
|
* @brief Get the port number.
|
||||||
|
* @return The requested port number.
|
||||||
|
*/
|
||||||
|
uint16_t getPort() {
|
||||||
|
return m_port;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
bool link();
|
||||||
|
bool unlink();
|
||||||
|
/**
|
||||||
|
* @brief Wait next extern connection
|
||||||
|
* @return element with the connection
|
||||||
|
*/
|
||||||
|
enet::Tcp waitNext();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,8 @@ def create(target, module_name):
|
|||||||
my_module.add_src_file([
|
my_module.add_src_file([
|
||||||
'enet/Udp.cpp',
|
'enet/Udp.cpp',
|
||||||
'enet/Tcp.cpp',
|
'enet/Tcp.cpp',
|
||||||
|
'enet/TcpServer.cpp',
|
||||||
|
'enet/TcpClient.cpp',
|
||||||
'enet/Http.cpp',
|
'enet/Http.cpp',
|
||||||
'enet/Ftp.cpp',
|
'enet/Ftp.cpp',
|
||||||
])
|
])
|
||||||
@ -43,6 +45,8 @@ def create(target, module_name):
|
|||||||
'enet/debug.h',
|
'enet/debug.h',
|
||||||
'enet/Udp.h',
|
'enet/Udp.h',
|
||||||
'enet/Tcp.h',
|
'enet/Tcp.h',
|
||||||
|
'enet/TcpServer.h',
|
||||||
|
'enet/TcpClient.h',
|
||||||
'enet/Http.h',
|
'enet/Http.h',
|
||||||
'enet/Ftp.h',
|
'enet/Ftp.h',
|
||||||
])
|
])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user