[DEV] add number of retry in parameter and some poll clean
This commit is contained in:
parent
fe937bbe64
commit
f0c425cd29
221
enet/Tcp.cpp
221
enet/Tcp.cpp
@ -69,8 +69,10 @@ enet::Tcp& enet::Tcp::operator = (enet::Tcp&& _obj) {
|
||||
|
||||
bool enet::Tcp::unlink() {
|
||||
if (m_socketId >= 0) {
|
||||
ENET_INFO("Close socket");
|
||||
ENET_INFO("Close socket (start)");
|
||||
shutdown(m_socketId, SHUT_RDWR);
|
||||
close(m_socketId);
|
||||
ENET_INFO("Close socket (done)");
|
||||
m_socketId = -1;
|
||||
}
|
||||
m_status = status::unlink;
|
||||
@ -85,183 +87,48 @@ int32_t enet::Tcp::read(void* _data, int32_t _maxLen) {
|
||||
return -1;
|
||||
}
|
||||
int32_t size = -1;
|
||||
#if 0
|
||||
size = ::read(m_socketId, _data, _maxLen);
|
||||
if ( size != 0
|
||||
&& errno == 2) {
|
||||
// simply the socket en empty
|
||||
} else if (errno != 0) {
|
||||
ENET_ERROR("PB when reading data on the FD : request=" << _maxLen << " have=" << size << ", erno=" << errno << "," << strerror(errno));
|
||||
m_status = status::error;
|
||||
return -1;
|
||||
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.
|
||||
int timeout = (3 * 60 * 1000);
|
||||
// Call poll() and wait 3 minutes for it to complete.
|
||||
ENET_VERBOSE("Waiting on poll()...");
|
||||
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.
|
||||
rc = recv(m_fds[0].fd, _data, _maxLen, 0);
|
||||
if (rc < 0) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
ENET_ERROR(" recv() failed");
|
||||
closeConn = true;
|
||||
}
|
||||
#else
|
||||
#ifndef SDFGSDFGSDFGSDFGSDFGSDFG
|
||||
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.
|
||||
int timeout = (3 * 60 * 1000);
|
||||
// Call poll() and wait 3 minutes for it to complete.
|
||||
ENET_VERBOSE("Waiting on poll()...");
|
||||
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. End program.\n");
|
||||
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.
|
||||
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_ERROR(" Connection closed");
|
||||
closeConn = true;
|
||||
}
|
||||
if (closeConn == false) {
|
||||
// Data was received
|
||||
size = rc;
|
||||
ENET_VERBOSE(" " << size << " bytes received");
|
||||
} 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_ERROR(" Set status at remote close ...");
|
||||
m_status = status::linkRemoteClose;
|
||||
}
|
||||
#else
|
||||
//Initialize the pollfd structure
|
||||
memset(m_fds, 0 , sizeof(m_fds));
|
||||
//Set up the initial listening socket
|
||||
m_fds[0].fd = m_socketId;
|
||||
m_fds[0].events = POLLIN;
|
||||
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.
|
||||
int timeout = (3 * 60 * 1000);
|
||||
//Loop waiting for incoming connects or for incoming data on any of the connected sockets.
|
||||
do {
|
||||
// Call poll() and wait 3 minutes for it to complete.
|
||||
ENET_INFO("Waiting on poll()...");
|
||||
int rc = poll(m_fds, nfds, timeout);
|
||||
// Check to see if the poll call failed.
|
||||
if (rc < 0) {
|
||||
ENET_ERROR(" poll() failed");
|
||||
break;
|
||||
}
|
||||
// Check to see if the 3 minute time out expired.
|
||||
if (rc == 0) {
|
||||
ENET_ERROR(" poll() timed out. End program.\n");
|
||||
break;
|
||||
}
|
||||
// One or more descriptors are readable. Need to determine which ones they are.
|
||||
int current_size = nfds;
|
||||
for (int32_t iii iii=0; iii<current_size; ++iii) {
|
||||
// Loop through to find the descriptors that returned POLLIN and determine whether it's the listening or the active connection.
|
||||
if(m_fds[iii].revents == 0) {
|
||||
continue;
|
||||
}
|
||||
// If revents is not POLLIN, it's an unexpected result, log and end the server.
|
||||
if(m_fds[iii].revents != POLLIN) {
|
||||
printf(" Error! revents = %d\n", m_fds[iii].revents);
|
||||
bool end_server = true; // TODO: dsfsdfsdf
|
||||
break;
|
||||
}
|
||||
if (m_fds[iii].fd == m_socketId) {
|
||||
// Listening descriptor is readable.
|
||||
ENET_INFO(" Listening socket is readable");
|
||||
// Accept all incoming connections that are queued up on the listening socket before we loop back and call poll again.
|
||||
do {
|
||||
// Accept each incoming connection. If accept fails with EWOULDBLOCK, then we have accepted all of them.
|
||||
// Any other failure on accept will cause us to end the server.
|
||||
new_sd = accept(listen_sd, nullptr, nullptr);
|
||||
if (new_sd < 0) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
ENET_ERROR(" accept() failed");
|
||||
end_server = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Add the new incoming connection to the pollfd structure
|
||||
ENET_ERROR(" New incoming connection - %d", new_sd);
|
||||
m_fds[nfds].fd = new_sd;
|
||||
m_fds[nfds].events = POLLIN;
|
||||
nfds++;
|
||||
// Loop back up and accept another incoming connection
|
||||
} while (new_sd != -1);
|
||||
} else {
|
||||
// This is not the listening socket, therefore an existing connection must be readable
|
||||
ENET_INFO(" Descriptor %d is readable", fds[iii].fd);
|
||||
close_conn = false;
|
||||
// Receive all incoming data on this socket before we loop back and call poll again.
|
||||
do {
|
||||
// Receive data on this connection until the recv fails with EWOULDBLOCK.
|
||||
// If any other failure occurs, we will close the connection.
|
||||
rc = recv(m_fds[iii].fd, buffer, sizeof(buffer), 0);
|
||||
if (rc < 0) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
perror(" recv() failed");
|
||||
close_conn = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Check to see if the connection has been closed by the client
|
||||
if (rc == 0) {
|
||||
ENET_ERROR(" Connection closed");
|
||||
close_conn = true;
|
||||
break;
|
||||
}
|
||||
// Data was received
|
||||
len = rc;
|
||||
ENET_INFO(" %d bytes received", len);
|
||||
// Echo the data back to the client
|
||||
rc = send(m_fds[i].fd, buffer, len, 0);
|
||||
if (rc < 0) {
|
||||
ENET_ERRO(" send() failed");
|
||||
close_conn = true;
|
||||
break;
|
||||
}
|
||||
} while(true);
|
||||
// If the close_conn flag was turned on, we need to clean up this active connection.
|
||||
// This clean up process includes removing the descriptor.
|
||||
if (close_conn) {
|
||||
close(m_fds[i].fd);
|
||||
m_fds[i].fd = -1;
|
||||
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.
|
||||
// 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) {
|
||||
compress_array = false;
|
||||
for (int32_t iii=0; iii<nfds; ++iii) {
|
||||
if (m_fds[i].fd == -1) {
|
||||
for(int32_t jjj = iii; jjj < nfds; ++jjj) {
|
||||
m_fds[jjj].fd = fds[jjj+1].fd;
|
||||
}
|
||||
nfds--;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (end_server == false);
|
||||
// Clean up all of the sockets that are open
|
||||
for (int32_t iii=0; iii<nfds; ++iii) {
|
||||
if(m_fds[iii].fd >= 0) {
|
||||
close(m_fds[iii].fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
// Check to see if the connection has been closed by the client
|
||||
if (rc == 0) {
|
||||
ENET_ERROR(" Connection closed");
|
||||
closeConn = true;
|
||||
}
|
||||
if (closeConn == false) {
|
||||
// Data was received
|
||||
size = rc;
|
||||
ENET_VERBOSE(" " << size << " bytes received");
|
||||
} 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_ERROR(" Set status at remote close ...");
|
||||
m_status = status::linkRemoteClose;
|
||||
}
|
||||
ENET_VERBOSE("read [STOP]");
|
||||
return size;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#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) {
|
||||
enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8_t _ip4, uint16_t _port, uint32_t _numberRetry) {
|
||||
std::string tmpname;
|
||||
tmpname = etk::to_string(_ip1);
|
||||
tmpname += ".";
|
||||
@ -25,13 +25,12 @@ enet::Tcp enet::connectTcpClient(uint8_t _ip1, uint8_t _ip2, uint8_t _ip3, uint8
|
||||
tmpname += etk::to_string(_ip3);
|
||||
tmpname += ".";
|
||||
tmpname += etk::to_string(_ip4);
|
||||
return std::move(enet::connectTcpClient(tmpname, _port));
|
||||
return std::move(enet::connectTcpClient(tmpname, _port, _numberRetry));
|
||||
}
|
||||
#define MAX_TEST_TIME (50)
|
||||
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port) {
|
||||
enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry) {
|
||||
int32_t socketId = -1;
|
||||
ENET_INFO("Start connection on " << _hostname << ":" << _port);
|
||||
for(int32_t iii=0; iii<MAX_TEST_TIME ;iii++) {
|
||||
for(int32_t iii=0; iii<_numberRetry ;iii++) {
|
||||
// open in Socket normal mode
|
||||
socketId = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socketId < 0) {
|
||||
@ -39,7 +38,7 @@ enet::Tcp enet::connectTcpClient(const std::string& _hostname, uint16_t _port) {
|
||||
usleep(200000);
|
||||
continue;
|
||||
}
|
||||
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << MAX_TEST_TIME << ")");
|
||||
ENET_INFO("Try connect on socket ... (" << iii+1 << "/" << _numberRetry << ")");
|
||||
struct sockaddr_in servAddr;
|
||||
struct hostent* server = gethostbyname(_hostname.c_str());
|
||||
if (server == nullptr) {
|
||||
|
@ -8,6 +8,6 @@
|
||||
#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);
|
||||
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(const std::string& _hostname, uint16_t _port, uint32_t _numberRetry=5);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user