Last active
July 24, 2024 12:43
-
-
Save MeexReay/540d412cb3263526b4a84c3eb066f9c3 to your computer and use it in GitHub Desktop.
tcp stream in c++ wow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <netinet/in.h> | |
#include <string> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
#include <unistd.h> | |
#include <optional> | |
#include <vector> | |
class TcpStream { | |
private: | |
int socket_id; | |
sockaddr_in server_address; | |
socklen_t server_addrlen; | |
public: | |
TcpStream(int p_socket_id, sockaddr_in p_server_address, socklen_t p_server_addrlen) { | |
socket_id = p_socket_id; | |
server_address = p_server_address; | |
server_addrlen = p_server_addrlen; | |
} | |
void close() { | |
::close(socket_id); | |
} | |
std::optional<TcpStream> accept() { | |
int new_socket = 0; | |
if ((new_socket = ::accept(socket_id, (struct sockaddr *)&server_address, (socklen_t*)&server_addrlen)) < 0) { | |
return std::optional<TcpStream>(); | |
} | |
return std::optional<TcpStream>(TcpStream(new_socket, server_address, server_addrlen)); | |
} | |
void write(std::vector<unsigned char> &buffer) { | |
::send(socket_id, static_cast<void*>(buffer.data()), buffer.size(), 0); | |
} | |
void read(std::vector<unsigned char> &buffer) { | |
::read(socket_id, static_cast<void*>(buffer.data()), buffer.size()); | |
} | |
static std::optional<TcpStream> connect(std::string addr) { | |
std::string host = ""; | |
std::string port = ""; | |
bool to_port = false; | |
for (char c: addr) { | |
if (c == ':') { | |
to_port = true; | |
continue; | |
} | |
if (to_port) port += c; | |
else host += c; | |
} | |
int sock; | |
struct sockaddr_in address; | |
int addrlen = sizeof(address); | |
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
return std::optional<TcpStream>(); | |
} | |
address.sin_family = AF_INET; | |
address.sin_port = htons(stoi(port)); | |
if(::inet_pton(AF_INET, host.c_str(), &address.sin_addr) <= 0) { | |
return std::optional<TcpStream>(); | |
} | |
if (::connect(sock, (struct sockaddr *)&address, sizeof(address)) < 0) { | |
return std::optional<TcpStream>(); | |
} | |
return std::optional<TcpStream>(TcpStream(sock,address,addrlen)); | |
} | |
static std::optional<TcpStream> bind(std::string addr) { | |
std::string host = ""; | |
std::string port = ""; | |
bool to_port = false; | |
for (char c: addr) { | |
if (c == ':') { | |
to_port = true; | |
continue; | |
} | |
if (to_port) port += c; | |
else host += c; | |
} | |
int sock; | |
struct sockaddr_in address; | |
int addrlen = sizeof(address); | |
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) { | |
return std::optional<TcpStream>(); | |
} | |
address.sin_family = AF_INET; | |
address.sin_addr.s_addr = INADDR_ANY; | |
address.sin_port = htons(stoi(port)); | |
if (::bind(sock, (struct sockaddr *)&address, sizeof(address)) < 0) { | |
return std::optional<TcpStream>(); | |
} | |
if (listen(sock, 3) < 0) { | |
return std::optional<TcpStream>(); | |
} | |
return std::optional<TcpStream>(TcpStream(sock,address,addrlen)); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment