@@ -28,12 +28,11 @@ SocketHandler::SocketHandler(std::shared_ptr<Poller> poller):
|
|||||||
connected(false),
|
connected(false),
|
||||||
connecting(false)
|
connecting(false)
|
||||||
{
|
{
|
||||||
this->init_socket();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketHandler::init_socket()
|
void SocketHandler::init_socket(const struct addrinfo* rp)
|
||||||
{
|
{
|
||||||
if ((this->socket = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
if ((this->socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
|
||||||
throw std::runtime_error("Could not create socket");
|
throw std::runtime_error("Could not create socket");
|
||||||
int optval = 1;
|
int optval = 1;
|
||||||
if (::setsockopt(this->socket, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
|
if (::setsockopt(this->socket, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
|
||||||
@@ -64,7 +63,7 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
|
|||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
hints.ai_flags = 0;
|
hints.ai_flags = 0;
|
||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_protocol = 0;
|
hints.ai_protocol = 0;
|
||||||
|
|
||||||
@@ -99,10 +98,19 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
|
|||||||
addr_res->ai_addr = &this->ai_addr;
|
addr_res->ai_addr = &this->ai_addr;
|
||||||
addr_res->ai_addrlen = this->ai_addrlen;
|
addr_res->ai_addrlen = this->ai_addrlen;
|
||||||
}
|
}
|
||||||
this->connecting = true;
|
|
||||||
|
|
||||||
for (struct addrinfo* rp = addr_res; rp; rp = rp->ai_next)
|
for (struct addrinfo* rp = addr_res; rp; rp = rp->ai_next)
|
||||||
{
|
{
|
||||||
|
if (!this->connecting)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
this->init_socket(rp);
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& error) {
|
||||||
|
log_error("Failed to init socket: " << error.what());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (::connect(this->socket, rp->ai_addr, rp->ai_addrlen) == 0
|
if (::connect(this->socket, rp->ai_addr, rp->ai_addrlen) == 0
|
||||||
|| errno == EISCONN)
|
|| errno == EISCONN)
|
||||||
{
|
{
|
||||||
@@ -116,6 +124,8 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
|
|||||||
else if (errno == EINPROGRESS || errno == EALREADY)
|
else if (errno == EINPROGRESS || errno == EALREADY)
|
||||||
{ // retry this process later, when the socket
|
{ // retry this process later, when the socket
|
||||||
// is ready to be written on.
|
// is ready to be written on.
|
||||||
|
this->connecting = true;
|
||||||
|
this->poller->add_socket_handler(this);
|
||||||
this->poller->watch_send_events(this);
|
this->poller->watch_send_events(this);
|
||||||
// Save the addrinfo structure, to use it on the next call
|
// Save the addrinfo structure, to use it on the next call
|
||||||
this->ai_addrlen = rp->ai_addrlen;
|
this->ai_addrlen = rp->ai_addrlen;
|
||||||
|
|||||||
@@ -26,9 +26,10 @@ public:
|
|||||||
explicit SocketHandler(std::shared_ptr<Poller> poller);
|
explicit SocketHandler(std::shared_ptr<Poller> poller);
|
||||||
virtual ~SocketHandler() {}
|
virtual ~SocketHandler() {}
|
||||||
/**
|
/**
|
||||||
* (re-)Initialize the socket
|
* Initialize the socket with the parameters contained in the given
|
||||||
|
* addrinfo structure.
|
||||||
*/
|
*/
|
||||||
void init_socket();
|
void init_socket(const struct addrinfo* rp);
|
||||||
/**
|
/**
|
||||||
* Connect to the remote server, and call on_connected() if this succeeds
|
* Connect to the remote server, and call on_connected() if this succeeds
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user