Finish implementation of synchronous host lookup.
This commit is contained in:
parent
66d8d81882
commit
344907b564
@ -279,8 +279,33 @@ inline int inet_pton(int af, const char* src, void* dest)
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
inline hostent* gethostbyaddr_r(const char *addr, int length, int type,
|
||||
hostent *result, char* buffer, int buflength, int* error)
|
||||
inline int gethostname(char* name, int namelen)
|
||||
{
|
||||
set_error(0);
|
||||
return error_wrapper(::gethostname(name, namelen));
|
||||
}
|
||||
|
||||
inline int translate_netdb_error(int error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case 0:
|
||||
return socket_error::success;
|
||||
case HOST_NOT_FOUND:
|
||||
return socket_error::host_not_found;
|
||||
case TRY_AGAIN:
|
||||
return socket_error::host_not_found_try_again;
|
||||
case NO_RECOVERY:
|
||||
return socket_error::no_recovery;
|
||||
case NO_DATA:
|
||||
return socket_error::no_host_data;
|
||||
default:
|
||||
return get_error();
|
||||
}
|
||||
}
|
||||
|
||||
inline hostent* gethostbyaddr_r(const char* addr, int length, int type,
|
||||
hostent* result, char* buffer, int buflength, int* error)
|
||||
{
|
||||
set_error(0);
|
||||
#if defined(_WIN32)
|
||||
@ -291,17 +316,20 @@ inline hostent* gethostbyaddr_r(const char *addr, int length, int type,
|
||||
*result = *ent_result;
|
||||
return result;
|
||||
#elif defined(__sun)
|
||||
return error_wrapper(::gethostbyaddr_r(addr, length, type, result, buffer,
|
||||
buflength, error));
|
||||
hostent* result = error_wrapper(::gethostbyaddr_r(addr, length, type, result,
|
||||
buffer, buflength, error));
|
||||
*error = translate_netdb_error(*error);
|
||||
return result;
|
||||
#else
|
||||
hostent* ent_result = 0;
|
||||
error_wrapper(::gethostbyaddr_r(addr, length, type, result, buffer,
|
||||
buflength, &ent_result, error));
|
||||
*error = translate_netdb_error(*error);
|
||||
return ent_result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline hostent* gethostbyname_r(const char *name, struct hostent *result,
|
||||
inline hostent* gethostbyname_r(const char* name, struct hostent* result,
|
||||
char* buffer, int buflength, int* error)
|
||||
{
|
||||
set_error(0);
|
||||
@ -313,12 +341,15 @@ inline hostent* gethostbyname_r(const char *name, struct hostent *result,
|
||||
*result = *ent_result;
|
||||
return result;
|
||||
#elif defined(__sun)
|
||||
return error_wrapper(::gethostbyname_r(name, result, buffer, buflength,
|
||||
error));
|
||||
hostent* result = error_wrapper(::gethostbyname_r(name, result, buffer,
|
||||
buflength, error));
|
||||
*error = translate_netdb_error(*error);
|
||||
return ent_result;
|
||||
#else
|
||||
hostent* ent_result = 0;
|
||||
error_wrapper(::gethostbyname_r(name, result, buffer, buflength, &ent_result,
|
||||
error));
|
||||
*error = translate_netdb_error(*error);
|
||||
return ent_result;
|
||||
#endif
|
||||
}
|
||||
|
@ -93,7 +93,9 @@ public:
|
||||
/**
|
||||
* This function is used to obtain host information for the local machine.
|
||||
*
|
||||
* @param h A host object that receives information about the local machine.
|
||||
* @param h A host object that receives information assocated with the
|
||||
* specified address. After successful completion of this function, the host
|
||||
* object is guaranteed to contain at least one address.
|
||||
*
|
||||
* @param error_handler The handler to be called when an error occurs. Copies
|
||||
* will be made of the handler as required. The equivalent function signature
|
||||
@ -116,7 +118,8 @@ public:
|
||||
* @param addr An address object that identifies a host.
|
||||
*
|
||||
* @param h A host object that receives information assocated with the
|
||||
* specified address.
|
||||
* specified address. After successful completion of this function, the host
|
||||
* object is guaranteed to contain at least one address.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
@ -133,7 +136,8 @@ public:
|
||||
* @param addr An address object that identifies a host.
|
||||
*
|
||||
* @param h A host object that receives information assocated with the
|
||||
* specified address.
|
||||
* specified address. After successful completion of this function, the host
|
||||
* object is guaranteed to contain at least one address.
|
||||
*
|
||||
* @param error_handler The handler to be called when an error occurs. Copies
|
||||
* will be made of the handler as required. The equivalent function signature
|
||||
|
@ -85,6 +85,11 @@ public:
|
||||
template <typename Error_Handler>
|
||||
void get_local_host(impl_type& impl, host& h, Error_Handler error_handler)
|
||||
{
|
||||
char name[1024];
|
||||
if (asio::detail::socket_ops::gethostname(name, sizeof(name)) != 0)
|
||||
error_handler(socket_error(asio::detail::socket_ops::get_error()));
|
||||
else
|
||||
get_host_by_name(impl, name, h, error_handler);
|
||||
}
|
||||
|
||||
/// Get host information for a specified address.
|
||||
@ -124,6 +129,7 @@ public:
|
||||
populate_host_object(h, ent);
|
||||
}
|
||||
|
||||
private:
|
||||
// Populate a host object from a hostent structure.
|
||||
void populate_host_object(host& h, hostent& ent)
|
||||
{
|
||||
@ -149,7 +155,6 @@ public:
|
||||
h.addresses.swap(tmp.addresses);
|
||||
}
|
||||
|
||||
private:
|
||||
// The demuxer used for dispatching handlers.
|
||||
Demuxer& demuxer_;
|
||||
};
|
||||
|
@ -30,8 +30,10 @@ namespace asio {
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define ASIO_SOCKET_ERROR(e) WSA ## e
|
||||
# define ASIO_NETDB_ERROR(e) WSA ## e
|
||||
#else
|
||||
# define ASIO_SOCKET_ERROR(e) e
|
||||
# define ASIO_NETDB_ERROR(e) 16384 + e
|
||||
#endif
|
||||
|
||||
/// The socket_error class is used to encapsulate socket error codes.
|
||||
@ -70,10 +72,10 @@ public:
|
||||
fault = ASIO_SOCKET_ERROR(EFAULT),
|
||||
|
||||
/// Host not found (authoritative).
|
||||
host_not_found = ASIO_SOCKET_ERROR(HOST_NOT_FOUND),
|
||||
host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND),
|
||||
|
||||
/// Host not found (non-authoritative).
|
||||
host_not_found_try_again = ASIO_SOCKET_ERROR(TRY_AGAIN),
|
||||
host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN),
|
||||
|
||||
/// No route to host.
|
||||
host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH),
|
||||
@ -106,7 +108,7 @@ public:
|
||||
no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS),
|
||||
|
||||
/// The host is valid but does not have address data.
|
||||
no_host_data = ASIO_SOCKET_ERROR(NO_DATA),
|
||||
no_host_data = ASIO_NETDB_ERROR(NO_DATA),
|
||||
|
||||
/// Cannot allocate memory.
|
||||
no_memory = ENOMEM,
|
||||
@ -118,7 +120,7 @@ public:
|
||||
no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT),
|
||||
|
||||
/// A non-recoverable error occurred.
|
||||
no_recovery = ASIO_SOCKET_ERROR(NO_RECOVERY),
|
||||
no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY),
|
||||
|
||||
/// Transport endpoint is not connected.
|
||||
not_connected = ASIO_SOCKET_ERROR(ENOTCONN),
|
||||
@ -205,12 +207,29 @@ public:
|
||||
msg.resize(msg.size() - 1);
|
||||
return msg;
|
||||
}
|
||||
#elif defined(__sun)
|
||||
#else // _WIN32
|
||||
switch (code_)
|
||||
{
|
||||
case host_not_found:
|
||||
return "Host not found (authoritative).";
|
||||
case host_not_found_try_again:
|
||||
return "Host not found (non-authoritative), try again later.";
|
||||
case no_recovery:
|
||||
return "A non-recoverable error occurred during database lookup.";
|
||||
case no_host_data:
|
||||
return "The name is valid, but it does not have associated data.";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if defined(__sun)
|
||||
return std::string(strerror(code_));
|
||||
#else
|
||||
#else // __sun
|
||||
if (code_ == operation_aborted)
|
||||
return "Operation cancelled.";
|
||||
char buf[256] = "";
|
||||
return std::string(strerror_r(code_, buf, sizeof(buf)));
|
||||
#endif
|
||||
#endif // __sun
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
struct unspecified_bool_type_t;
|
||||
|
@ -10,13 +10,12 @@ typedef std::deque<chat_message> chat_message_queue;
|
||||
class chat_client
|
||||
{
|
||||
public:
|
||||
chat_client(asio::demuxer& d, short port, const char* host)
|
||||
chat_client(asio::demuxer& d, const asio::ipv4::tcp::endpoint& endpoint)
|
||||
: demuxer_(d),
|
||||
connector_(d),
|
||||
socket_(d)
|
||||
{
|
||||
connector_.async_connect(socket_,
|
||||
asio::ipv4::tcp::endpoint(port, asio::ipv4::address(host)),
|
||||
connector_.async_connect(socket_, endpoint,
|
||||
boost::bind(&chat_client::handle_connect, this, asio::arg::error));
|
||||
}
|
||||
|
||||
@ -133,7 +132,12 @@ int main(int argc, char* argv[])
|
||||
asio::demuxer d;
|
||||
|
||||
using namespace std; // For atoi, strlen and memcpy.
|
||||
chat_client c(d, atoi(argv[2]), argv[1]);
|
||||
asio::ipv4::host_resolver hr(d);
|
||||
asio::ipv4::host h;
|
||||
hr.get_host_by_name(argv[1], h);
|
||||
asio::ipv4::tcp::endpoint ep(atoi(argv[2]), h.addresses[0]);
|
||||
|
||||
chat_client c(d, ep);
|
||||
|
||||
asio::detail::thread t(boost::bind(&asio::demuxer::run, &d));
|
||||
|
||||
|
@ -161,9 +161,9 @@ typedef boost::shared_ptr<chat_session> chat_session_ptr;
|
||||
class chat_server
|
||||
{
|
||||
public:
|
||||
chat_server(asio::demuxer& d, short port)
|
||||
chat_server(asio::demuxer& d, const asio::ipv4::tcp::endpoint& endpoint)
|
||||
: demuxer_(d),
|
||||
acceptor_(d, asio::ipv4::tcp::endpoint(port))
|
||||
acceptor_(d, endpoint)
|
||||
{
|
||||
chat_session_ptr new_session(new chat_session(demuxer_, room_));
|
||||
acceptor_.async_accept(new_session->socket(),
|
||||
@ -210,7 +210,8 @@ int main(int argc, char* argv[])
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
using namespace std; // For atoi.
|
||||
chat_server_ptr server(new chat_server(d, atoi(argv[i])));
|
||||
asio::ipv4::tcp::endpoint endpoint(atoi(argv[i]));
|
||||
chat_server_ptr server(new chat_server(d, endpoint));
|
||||
servers.push_back(server);
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,15 @@ int main(int argc, char* argv[])
|
||||
|
||||
asio::demuxer d;
|
||||
|
||||
asio::ipv4::host_resolver hr(d);
|
||||
asio::ipv4::host h;
|
||||
hr.get_host_by_name(argv[1], h);
|
||||
asio::ipv4::tcp::endpoint ep(atoi(argv[2]), h.addresses[0]);
|
||||
|
||||
using namespace std; // For atoi and strlen.
|
||||
asio::stream_socket s(d);
|
||||
asio::socket_connector c(d);
|
||||
c.connect(s,asio::ipv4::tcp::endpoint(atoi(argv[2]),
|
||||
asio::ipv4::address(argv[1])));
|
||||
c.connect(s, ep);
|
||||
|
||||
std::cout << "Enter message: ";
|
||||
char request[max_length];
|
||||
|
@ -19,13 +19,16 @@ int main(int argc, char* argv[])
|
||||
|
||||
asio::dgram_socket s(d, asio::ipv4::udp::endpoint(0));
|
||||
|
||||
asio::ipv4::host_resolver hr(d);
|
||||
asio::ipv4::host h;
|
||||
hr.get_host_by_name(argv[1], h);
|
||||
asio::ipv4::udp::endpoint receiver_endpoint(atoi(argv[2]), h.addresses[0]);
|
||||
|
||||
using namespace std; // For atoi and strlen.
|
||||
std::cout << "Enter message: ";
|
||||
char request[max_length];
|
||||
std::cin.getline(request, max_length);
|
||||
size_t request_length = strlen(request);
|
||||
asio::ipv4::udp::endpoint receiver_endpoint(atoi(argv[2]),
|
||||
asio::ipv4::address(argv[1]));
|
||||
s.sendto(request, request_length, receiver_endpoint);
|
||||
|
||||
char reply[max_length];
|
||||
|
@ -13,11 +13,15 @@ int main(int argc, char* argv[])
|
||||
|
||||
asio::demuxer demuxer;
|
||||
|
||||
asio::ipv4::host_resolver host_resolver(demuxer);
|
||||
asio::ipv4::host host;
|
||||
host_resolver.get_host_by_name(argv[1], host);
|
||||
asio::ipv4::tcp::endpoint remote_endpoint(13, host.addresses[0]);
|
||||
|
||||
asio::stream_socket socket(demuxer);
|
||||
|
||||
asio::socket_connector connector(demuxer);
|
||||
connector.connect(socket,
|
||||
asio::ipv4::tcp::endpoint(13, asio::ipv4::address(argv[1])));
|
||||
connector.connect(socket, remote_endpoint);
|
||||
|
||||
char buf[128];
|
||||
while (size_t len = socket.recv(buf, sizeof(buf)))
|
||||
|
@ -15,13 +15,17 @@ int main(int argc, char* argv[])
|
||||
|
||||
asio::dgram_socket socket(demuxer, asio::ipv4::udp::endpoint(0));
|
||||
|
||||
asio::ipv4::host_resolver host_resolver(demuxer);
|
||||
asio::ipv4::host host;
|
||||
host_resolver.get_host_by_name(argv[1], host);
|
||||
asio::ipv4::udp::endpoint receiver_endpoint(13, host.addresses[0]);
|
||||
|
||||
char send_buf[1] = { 0 };
|
||||
socket.sendto(send_buf, sizeof(send_buf),
|
||||
asio::ipv4::udp::endpoint(13, asio::ipv4::address(argv[1])));
|
||||
socket.sendto(send_buf, sizeof(send_buf), receiver_endpoint);
|
||||
|
||||
char recv_buf[128];
|
||||
asio::ipv4::udp::endpoint remote_endpoint;
|
||||
size_t len = socket.recvfrom(recv_buf, sizeof(recv_buf), remote_endpoint);
|
||||
asio::ipv4::udp::endpoint sender_endpoint;
|
||||
size_t len = socket.recvfrom(recv_buf, sizeof(recv_buf), sender_endpoint);
|
||||
std::cout.write(recv_buf, len);
|
||||
}
|
||||
catch (asio::socket_error& e)
|
||||
|
@ -158,13 +158,13 @@ private:
|
||||
class client
|
||||
{
|
||||
public:
|
||||
client(demuxer& d, const char* host, short port, size_t block_size,
|
||||
size_t session_count, int timeout)
|
||||
client(demuxer& d, const ipv4::tcp::endpoint& server_endpoint,
|
||||
size_t block_size, size_t session_count, int timeout)
|
||||
: demuxer_(d),
|
||||
dispatcher_(d),
|
||||
stop_timer_(d, timer::from_now, timeout),
|
||||
connector_(d),
|
||||
server_endpoint_(port, ipv4::address(host)),
|
||||
server_endpoint_(server_endpoint),
|
||||
block_size_(block_size),
|
||||
max_session_count_(session_count),
|
||||
sessions_(),
|
||||
@ -250,7 +250,12 @@ int main(int argc, char* argv[])
|
||||
|
||||
demuxer d;
|
||||
|
||||
client c(d, host, port, block_size, session_count, timeout);
|
||||
ipv4::host_resolver hr(d);
|
||||
ipv4::host h;
|
||||
hr.get_host_by_name(host, h);
|
||||
ipv4::tcp::endpoint ep(port, h.addresses[0]);
|
||||
|
||||
client c(d, ep, block_size, session_count, timeout);
|
||||
|
||||
std::list<thread*> threads;
|
||||
while (--thread_count > 0)
|
||||
|
@ -124,14 +124,14 @@ private:
|
||||
class server
|
||||
{
|
||||
public:
|
||||
server(demuxer& d, short port, size_t block_size)
|
||||
server(demuxer& d, const ipv4::tcp::endpoint& endpoint, size_t block_size)
|
||||
: demuxer_(d),
|
||||
acceptor_(d),
|
||||
block_size_(block_size)
|
||||
{
|
||||
acceptor_.open(ipv4::tcp());
|
||||
acceptor_.set_option(socket_option::reuse_address(1));
|
||||
acceptor_.bind(ipv4::tcp::endpoint(port));
|
||||
acceptor_.bind(endpoint);
|
||||
acceptor_.listen();
|
||||
|
||||
session* new_session = new session(demuxer_, block_size_);
|
||||
@ -177,7 +177,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
demuxer d;
|
||||
|
||||
server s(d, port, block_size);
|
||||
server s(d, ipv4::tcp::endpoint(port), block_size);
|
||||
|
||||
// Threads not currently supported in this test.
|
||||
std::list<thread*> threads;
|
||||
|
Loading…
Reference in New Issue
Block a user