extern "C" { #include #include #include #include #include #include #include #include } #include #include #include #include #include #include TCPClient::TCPClient() { sock = 0; family = 0; } std::expected TCPClient::Connect(const std::string naddress, const int port) { struct sockaddr_in sa; if (inet_pton(AF_INET, address.c_str(), &(sa.sin_addr)) == 1) { family = AF_INET; } else if (inet_pton(AF_INET6, address.c_str(), &(sa.sin_addr)) == 1) { family = AF_INET6; } else { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Incorrect address " + naddress); } sock = socket(family, SOCK_STREAM, 0); if (sock < 0) { return std::unexpected("Error opening socket"); } struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); const char* addr = address.data(); if (inet_pton(AF_INET, addr, &serv_addr.sin_addr) <= 0) { return std::unexpected("Invalid server IP address"); } struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout) < 0) { return std::unexpected("Set timeout error"); } if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof timeout) < 0) { return std::unexpected("Set timeout error"); } if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { return std::unexpected("Connecting error"); } return {}; } std::expected TCPClient::Write(std::span payload) { int n = 0; if ((n = write(sock, payload.data(), payload.size())) < 0) { return std::unexpected("Write error"); } return n; } std::expected TCPClient::Write(std::string payload) { int n = 0; if ((n = write(sock, payload.data(), payload.size())) < 0) { return std::unexpected("Write error"); } return n; } std::expected TCPClient::Read(std::vector* buffer) { int n = 0; if ((n = read(sock, buffer->data(), buffer->size())) < 0) { return std::unexpected("Read error"); } return n; } std::expected TCPClient::Read(std::vector* buffer) { return read(sock, buffer->data(), buffer->size()); }