working commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
|||||||
|
extern "C" {
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <expected>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <span>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <tcpclient.hpp>
|
||||||
|
|
||||||
|
TCPClient::TCPClient() {
|
||||||
|
sock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::expected<void, std::string> 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<int, std::string> TCPClient::writeBytes(std::span<const std::byte> payload) {
|
||||||
|
int n = 0;
|
||||||
|
if ((n = write(sock, payload.data(), payload.size())) < 0) {
|
||||||
|
return std::unexpected("Write error");
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::expected<int, std::string> 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<int, std::string> TCPClient::readBytes(std::vector<std::byte>* buffer) {
|
||||||
|
int n = 0;
|
||||||
|
if ((n = read(sock, buffer->data(), buffer->size())) < 0) {
|
||||||
|
return std::unexpected("Read error");
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::expected<int, std::string> TCPClient::readBytes(std::vector<uint8_t>* buffer) {
|
||||||
|
return read(sock, buffer->data(), buffer->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
#include <expected>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <span>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class TCPClient {
|
||||||
|
private:
|
||||||
|
int sock;
|
||||||
|
public:
|
||||||
|
TCPClient();
|
||||||
|
std::expected<void, std::string> conn(std::string address, const int port);
|
||||||
|
std::expected<int, std::string> writeBytes(std::span<const std::byte> payload);
|
||||||
|
std::expected<int, std::string> writeBytes(std::string payload);
|
||||||
|
std::expected<int, std::string> readBytes(std::vector<std::byte>* buffer);
|
||||||
|
std::expected<int, std::string> readBytes(std::vector<uint8_t>* buffer);
|
||||||
|
|
||||||
|
~TCPClient() {
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
#include <expected>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <span>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <tcpclient.hpp>
|
||||||
|
|
||||||
|
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<uint8_t> 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;
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <semaphore>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user