AddressInfos [] = AddressInfo; TCP v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 06 Aug 2022 00:33:40 +0200
branchv_0
changeset 14 86feef4b6ee6
parent 13 c29b13a659a7
child 15 290c58261df9
AddressInfos [] = AddressInfo; TCP
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 <typename T> 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> 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<sockaddr_in>(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<Socket> open(const SocketOptions& options) {
-		std::shared_ptr<TCPClientSocket> s = std::make_shared<TCPClientSocket>();
-		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<TCPClientSocket>(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");
 	}