Finish tcp client socket

This commit is contained in:
momo5502
2025-01-12 08:23:47 +01:00
parent 21e2f6f999
commit 8333c25f2c
9 changed files with 57 additions and 30 deletions

View File

@@ -38,7 +38,7 @@ namespace network
this->address_.sa_family = AF_UNSPEC;
}
address::address(const std::string& addr, const std::optional<int>& family)
address::address(const std::string_view addr, const std::optional<int>& family)
: address()
{
this->parse(addr, family);
@@ -286,7 +286,7 @@ namespace network
return is_ipv4() || is_ipv6();
}
void address::parse(std::string addr, const std::optional<int>& family)
void address::parse(std::string_view addr, const std::optional<int>& family)
{
std::optional<uint16_t> port_value{};
@@ -298,7 +298,7 @@ namespace network
addr = addr.substr(0, pos);
}
this->resolve(addr, family);
this->resolve(std::string(addr), family);
if (port_value)
{

View File

@@ -26,6 +26,7 @@
#endif
#include <string>
#include <string_view>
#include <vector>
#include <optional>
@@ -42,7 +43,7 @@ namespace network
{
public:
address();
address(const std::string& addr, const std::optional<int>& family = {});
address(std::string_view addr, const std::optional<int>& family = std::nullopt);
address(const sockaddr_in& addr);
address(const sockaddr_in6& addr);
address(const sockaddr* addr, socklen_t length);
@@ -91,7 +92,7 @@ namespace network
sockaddr_storage storage_;
};
void parse(std::string addr, const std::optional<int>& family = {});
void parse(std::string_view addr, const std::optional<int>& family = {});
void resolve(const std::string& hostname, const std::optional<int>& family = {});
};
}

View File

@@ -62,9 +62,9 @@ namespace network
}
}
bool socket::bind_port(const address& target)
bool socket::bind(const address& target)
{
return bind(this->socket_, &target.get_addr(), target.get_size()) == 0;
return ::bind(this->socket_, &target.get_addr(), target.get_size()) == 0;
}
bool socket::set_blocking(const bool blocking)

View File

@@ -11,6 +11,7 @@ using send_size = int;
#define GET_SOCKET_ERROR() (WSAGetLastError())
#define poll WSAPoll
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
#define SHUT_RDWR SD_BOTH
#else
using SOCKET = int;
using send_size = size_t;
@@ -31,7 +32,7 @@ namespace network
socket(SOCKET s);
socket(int af, int type, int protocol);
~socket();
virtual ~socket();
socket(const socket& obj) = delete;
socket& operator=(const socket& obj) = delete;
@@ -41,7 +42,7 @@ namespace network
operator bool() const;
bool bind_port(const address& target);
bool bind(const address& target);
bool set_blocking(bool blocking);
static bool set_blocking(SOCKET s, bool blocking);

View File

@@ -2,12 +2,24 @@
namespace network
{
tcp_client_socket::tcp_client_socket(SOCKET s, const address& target)
: socket(s),
target_(target)
tcp_client_socket::tcp_client_socket(const int af)
: socket(af, SOCK_STREAM, IPPROTO_TCP)
{
}
tcp_client_socket::tcp_client_socket(SOCKET s)
: socket(s)
{
}
tcp_client_socket::~tcp_client_socket()
{
if (*this && this->get_target())
{
::shutdown(this->get_socket(), SHUT_RDWR);
}
}
bool tcp_client_socket::send(const void* data, const size_t size) const
{
const auto res = ::send(this->get_socket(), static_cast<const char*>(data), static_cast<send_size>(size), 0);
@@ -33,8 +45,26 @@ namespace network
return true;
}
address tcp_client_socket::get_target() const
std::optional<address> tcp_client_socket::get_target() const
{
return this->target_;
address a{};
auto len = a.get_max_size();
if (getpeername(this->get_socket(), &a.get_addr(), &len) == SOCKET_ERROR)
{
return std::nullopt;
}
return a;
}
bool tcp_client_socket::connect(const address& target)
{
if (::connect(this->get_socket(), &target.get_addr(), target.get_size()) != SOCKET_ERROR)
{
return true;
}
const auto error = GET_SOCKET_ERROR();
return error == SOCK_WOULDBLOCK;
}
}

View File

@@ -10,10 +10,11 @@ namespace network
class tcp_client_socket : public socket
{
// TODO: Construct and connect client!
public:
tcp_client_socket(int af);
tcp_client_socket() = default;
~tcp_client_socket() = default;
~tcp_client_socket() override;
tcp_client_socket(tcp_client_socket&& obj) noexcept = default;
tcp_client_socket& operator=(tcp_client_socket&& obj) noexcept = default;
@@ -22,12 +23,12 @@ namespace network
[[maybe_unused]] bool send(std::string_view data) const;
bool receive(std::string& data) const;
address get_target() const;
std::optional<address> get_target() const;
bool connect(const address& target);
private:
address target_{};
friend tcp_server_socket;
tcp_client_socket(SOCKET s, const address& target);
tcp_client_socket(SOCKET s);
};
}

View File

@@ -13,14 +13,7 @@ namespace network
address a{};
auto len = a.get_max_size();
auto s = ::accept(this->get_socket(), &a.get_addr(), &len);
if (s == INVALID_SOCKET)
{
return {};
}
return tcp_client_socket{s, a};
return ::accept(this->get_socket(), &a.get_addr(), &len);
}
void tcp_server_socket::listen()

View File

@@ -7,10 +7,11 @@ namespace network
{
class tcp_server_socket : public socket
{
public:
tcp_server_socket(int af);
tcp_server_socket() = default;
~tcp_server_socket() = default;
~tcp_server_socket() override = default;
tcp_server_socket(tcp_server_socket&& obj) noexcept = default;
tcp_server_socket& operator=(tcp_server_socket&& obj) noexcept = default;

View File

@@ -10,7 +10,7 @@ namespace network
{
udp_socket(int af);
udp_socket() = default;
~udp_socket() = default;
~udp_socket() override = default;
udp_socket(udp_socket&& obj) noexcept = default;
udp_socket& operator=(udp_socket&& obj) noexcept = default;