diff --git a/tcpclient.cpp b/tcpclient.cpp new file mode 100644 index 0000000..abebe53 --- /dev/null +++ b/tcpclient.cpp @@ -0,0 +1,84 @@ +extern "C" { +#include +#include +#include +#include +#include +#include +#include +#include +} + +#include +#include +#include +#include +#include + +#include + +TCPClient::TCPClient() { + sock = 0; +} + +std::expected TCPClient::conn(const std::string address, const int port) { + sock = socket(AF_INET, 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 = 3; + 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::writeBytes(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::writeBytes(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::readBytes(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::readBytes(std::vector* buffer) { + return read(sock, buffer->data(), buffer->size()); +} + + diff --git a/tcpclient.hpp b/tcpclient.hpp new file mode 100644 index 0000000..0b7c1bb --- /dev/null +++ b/tcpclient.hpp @@ -0,0 +1,22 @@ + +#include +#include +#include +#include +#include + +class TCPClient { +private: + int sock; +public: + TCPClient(); + std::expected conn(std::string address, const int port); + std::expected writeBytes(std::span payload); + std::expected writeBytes(std::string payload); + std::expected readBytes(std::vector* buffer); + std::expected readBytes(std::vector* buffer); + + ~TCPClient() { + close(sock); + } +}; diff --git a/tcpclient_test.cpp b/tcpclient_test.cpp new file mode 100644 index 0000000..dc3f007 --- /dev/null +++ b/tcpclient_test.cpp @@ -0,0 +1,34 @@ + +#include +#include +#include +#include +#include + +#include + +int main( int argc, char** argv) { + TCPClient client; + auto res = client.conn("209.51.188.116", 80); + if (!res) { + std::cerr << res.error() << std::endl; + return 1; + } + auto wSize = client.writeBytes("GET / HTTP/1.1\n\n\n"); + if (!wSize) { + std::cerr << wSize.error() << std::endl; + return 1; + } + + std::vector buffer; + buffer.resize(2048); + auto rSize = client.readBytes(&buffer); + if (!rSize) { + std::cerr << rSize.error() << std::endl; + return 1; + } + std::cout << rSize.value() << std::endl; + + std::string s(buffer.begin(), buffer.end()); + std::cout << std::format("{}", s) << std::endl; +} diff --git a/tunclient.hpp b/tunclient.hpp index a510f1d..236ac92 100644 --- a/tunclient.hpp +++ b/tunclient.hpp @@ -1,5 +1,4 @@ - #include #include #include diff --git a/works/thrsema/thr.cpp b/works/thrsema/thr.cpp new file mode 100644 index 0000000..25f89c3 --- /dev/null +++ b/works/thrsema/thr.cpp @@ -0,0 +1,41 @@ + +#include +#include +#include +#include + +using namespace std::chrono_literals; + + +void worker(int id, std::binary_semaphore* wait, std::binary_semaphore* sign) { + for (int i = 0; i < 5; i++) { + std::cout << std::format("worker {}: working {}\n", id, i); + std::chrono::milliseconds timesleep(1s); + std::this_thread::sleep_for(timesleep); + if (sign->try_acquire()) { + std::cout << std::format("worker {}: break\n", id); + break; + } + } + wait->release(); +} + +int main() { + std::binary_semaphore wait(0); + std::binary_semaphore sign(0); + + std::thread t1(worker, 1, &wait, &sign); + t1.detach(); + + std::chrono::milliseconds timesleep(1s); + std::this_thread::sleep_for(timesleep); + sign.release(); + std::cout << "main: wait worker\n"; + wait.acquire(); + std::cout << "main: worker finished\n"; + + std::this_thread::sleep_for(timesleep); + + std::cout << "main: exit\n"; +} +