# HG changeset patch # User František Kučera # Date 1659738820 -7200 # Node ID 86feef4b6ee61e22e96cef44039a729233c70884 # Parent c29b13a659a7b6fdcf33c3bf94d47dfaafac7155 AddressInfos [] = AddressInfo; TCP diff -r c29b13a659a7 -r 86feef4b6ee6 src/Socket.cpp --- a/src/Socket.cpp Sat Aug 06 00:27:22 2022 +0200 +++ b/src/Socket.cpp Sat Aug 06 00:33:40 2022 +0200 @@ -64,11 +64,6 @@ else throw std::logic_error("Got error result: " + std::to_string(result) + " - " + message); } -template static T* castAddress(addrinfo* ai, sa_family_t family) { - if (ai && ai->ai_family == family && sizeof (T) == ai->ai_addrlen) return (T*) ai->ai_addr; - else return nullptr; -} - class AddressInfos { private: std::shared_ptr addrInfo; @@ -112,10 +107,6 @@ return AddressInfos(addrInfo); } - const sockaddr* getSocketAddress() { - return addrInfo->ai_addr; - } - const std::size_t size() const { std::size_t size = 0; for (addrinfo* ai = addrInfo.get(); ai; ai = ai->ai_next) size++; @@ -133,36 +124,6 @@ }; -// TODO: delete getAddress() - -static in_addr_t getAddress(const std::string& host) { - struct addrinfo query; - memset(&query, sizeof (query), 0); - query.ai_family = AF_UNSPEC; - query.ai_socktype = SOCK_STREAM; - query.ai_protocol = IPPROTO_TCP; - query.ai_flags = AI_ALL; - - struct addrinfo* addrInfo; - check(getaddrinfo(host.c_str(), "", &query, &addrInfo), "getaddrinfo"); - - if (addrInfo) { - for (addrinfo* ai = addrInfo; ai; ai = ai->ai_next) { - if (sockaddr_in * sa = castAddress(ai, AF_INET)) { - in_addr_t address = sa->sin_addr.s_addr; - freeaddrinfo(addrInfo); - return address; - - } - } - } - - freeaddrinfo(addrInfo); - - // TODO: rather throw exception – requires IP address in the host string: - return inet_addr(host.c_str()); -} - class UDPClientSocket : public Socket { private: AddressInfos remoteAddresses; @@ -199,21 +160,26 @@ class TCPClientSocket : public Socket { private: - struct sockaddr_in remoteAddress; + AddressInfos remoteAddresses; + + TCPClientSocket(AddressInfos remoteAddresses) : remoteAddresses(remoteAddresses) { + } public: static std::shared_ptr open(const SocketOptions& options) { - std::shared_ptr s = std::make_shared(); - memset((char *) &s->remoteAddress, 0, sizeof (s->remoteAddress)); - s->remoteAddress.sin_family = AF_INET; - s->remoteAddress.sin_addr.s_addr = getAddress(findOption(options, OPTION_HOST, true).c_str()); // TODO: use getaddrinfo() instead (because of error -1 = 255.255.255.255) - s->remoteAddress.sin_port = htons(std::stoi(findOption(options, OPTION_PORT, true))); - return s; + AddressInfos remoteAddresses = AddressInfos::getAddressInfos( + findOption(options, OPTION_HOST, true), + findOption(options, OPTION_PORT, true), + SOCK_STREAM, + IPPROTO_TCP); + + return std::shared_ptr(new TCPClientSocket(remoteAddresses)); } void send(const std::string& message) override { - FD s(::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); - check(::connect(s.getFD(), (sockaddr*) & remoteAddress, sizeof (remoteAddress)), "connect socket"); + auto ai = remoteAddresses[0].ai; + FD s(::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)); + check(::connect(s.getFD(), ai->ai_addr, ai->ai_addrlen), "connect socket"); ssize_t written = ::write(s.getFD(), message.c_str(), message.size()); if (written != message.size()) throw std::logic_error("writing to the socket failed"); }