added connect timeout, fixed non-closed sockets on connect error
This commit is contained in:
@@ -71,11 +71,10 @@ bool HttpClient::parseUrl(const string& url, string& proto, string& host, uint16
|
|||||||
|
|
||||||
bool HttpClient::connect(const string& host, const uint16_t port, const string& userAgent, const int timeout) {
|
bool HttpClient::connect(const string& host, const uint16_t port, const string& userAgent, const int timeout) {
|
||||||
disconnect();
|
disconnect();
|
||||||
m_socket = m_client.connect(host, port);
|
m_socket = m_client.connect(host, port, timeout);
|
||||||
if (!m_socket) {
|
if (!m_socket) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_socket->setTimeout(timeout);
|
|
||||||
m_host = host;
|
m_host = host;
|
||||||
m_port = port;
|
m_port = port;
|
||||||
m_timeout = timeout;
|
m_timeout = timeout;
|
||||||
@@ -88,11 +87,10 @@ bool HttpClient::reconnect() {
|
|||||||
if (m_host.empty() || !m_port) {
|
if (m_host.empty() || !m_port) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_socket = m_client.connect(m_host, m_port);
|
m_socket = m_client.connect(m_host, m_port, m_timeout);
|
||||||
if (!m_socket) {
|
if (!m_socket) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_socket->setTimeout(m_timeout);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,18 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lib/utils/tcpsocket.h"
|
#include "lib/utils/tcpsocket.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef HAVE_PPOLL
|
||||||
|
# include <poll.h>
|
||||||
|
#endif
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace ebusd {
|
namespace ebusd {
|
||||||
@@ -37,7 +44,7 @@ bool TCPSocket::isValid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TCPSocket* TCPClient::connect(const string& server, const uint16_t& port) {
|
TCPSocket* TCPClient::connect(const string& server, const uint16_t& port, int timeout) {
|
||||||
socketaddress address;
|
socketaddress address;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -65,11 +72,53 @@ TCPSocket* TCPClient::connect(const string& server, const uint16_t& port) {
|
|||||||
if (sfd < 0) {
|
if (sfd < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ret = ::connect(sfd, (struct sockaddr*) &address, sizeof(address));
|
#ifndef HAVE_PPOLL
|
||||||
if (ret < 0) {
|
#ifndef HAVE_PSELECT
|
||||||
|
timeout = 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
if (timeout > 0 && fcntl(sfd, F_SETFL, O_NONBLOCK) < 0) { // set non-blocking
|
||||||
|
close(sfd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return new TCPSocket(sfd, &address);
|
ret = ::connect(sfd, (struct sockaddr *) &address, sizeof(address));
|
||||||
|
if (ret != 0) {
|
||||||
|
if (ret < 0 && (timeout <= 0 || errno != EINPROGRESS)) {
|
||||||
|
close(sfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (timeout > 0) {
|
||||||
|
struct timespec tdiff;
|
||||||
|
tdiff.tv_sec = timeout;
|
||||||
|
tdiff.tv_nsec = 0;
|
||||||
|
#ifdef HAVE_PPOLL
|
||||||
|
nfds_t nfds = 1;
|
||||||
|
struct pollfd fds[nfds];
|
||||||
|
memset(fds, 0, sizeof(fds));
|
||||||
|
fds[0].fd = sfd;
|
||||||
|
fds[0].events = POLLIN|POLLOUT;
|
||||||
|
ret = ppoll(fds, nfds, &tdiff, NULL);
|
||||||
|
#else
|
||||||
|
fd_set readfds, writefds;
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(sfd, &readfds);
|
||||||
|
ret = pselect(sfd + 1, &readfds, &writefds, NULL, &tdiff, NULL);
|
||||||
|
#endif
|
||||||
|
if (ret == -1 || ret == 0) {
|
||||||
|
close(sfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (timeout > 0 && fcntl(sfd, F_SETFL, 0) < 0) { // set blocking again
|
||||||
|
close(sfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
TCPSocket* s = new TCPSocket(sfd, &address);
|
||||||
|
if (timeout > 0) {
|
||||||
|
s->setTimeout(timeout);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -133,9 +133,11 @@ class TCPClient {
|
|||||||
* initiate a tcp socket connection to a listening server.
|
* initiate a tcp socket connection to a listening server.
|
||||||
* @param server the server name or ip address to connect.
|
* @param server the server name or ip address to connect.
|
||||||
* @param port the tcp port.
|
* @param port the tcp port.
|
||||||
|
* @param timeout the connect, send, and receive timeout in seconds, or 0.
|
||||||
* @return pointer to an opened tcp socket.
|
* @return pointer to an opened tcp socket.
|
||||||
*/
|
*/
|
||||||
TCPSocket* connect(const string& server, const uint16_t& port);
|
TCPSocket* connect(const string& server, const uint16_t& port, int timeout = 0);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user