Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created March 15, 2025 15:47
Show Gist options
  • Save sunmeat/3eb4334238569d07aa8495fc567fef8f to your computer and use it in GitHub Desktop.
Save sunmeat/3eb4334238569d07aa8495fc567fef8f to your computer and use it in GitHub Desktop.
OOP TCP + OOP threads: CLIENT SIDE
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <windows.h>
#include <ws2tcpip.h>
#include <thread>
#include <atomic>
#include <string>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define PAUSE 1
class TcpClient {
private:
SOCKET connectSocket;
atomic<bool> running;
bool initializeWinsock() {
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0) {
cerr << "Failed to initialize Winsock: " << result << "\n";
return false;
}
return true;
}
bool createAndConnectSocket(const char* ip, const char* port) {
addrinfo hints = {};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
addrinfo* result = nullptr;
if (getaddrinfo(ip, port, &hints, &result) != 0) {
cerr << "getaddrinfo failed.\n";
WSACleanup();
return false;
}
for (addrinfo* ptr = result; ptr != nullptr; ptr = ptr->ai_next) {
connectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (connectSocket == INVALID_SOCKET) {
cerr << "Failed to create socket.\n";
continue;
}
if (connect(connectSocket, ptr->ai_addr, (int)ptr->ai_addrlen) == SOCKET_ERROR) {
closesocket(connectSocket);
connectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (connectSocket == INVALID_SOCKET) {
cerr << "Unable to connect to server!\n";
WSACleanup();
return false;
}
return true;
}
void sender() {
while (running) {
string message;
cout << "Введите сообщение для сервера: ";
getline(cin, message);
if (send(connectSocket, message.c_str(), static_cast<int>(message.length()), 0) == SOCKET_ERROR) {
cerr << "Send failed: " << WSAGetLastError() << "\n";
running = false;
break;
}
else {
cout << "Сообщение отправлено на сервер: " << message << "\n";
}
Sleep(PAUSE);
}
}
void receiver() {
char buffer[DEFAULT_BUFLEN];
while (running) {
int result = recv(connectSocket, buffer, DEFAULT_BUFLEN, 0);
if (result > 0) {
buffer[result] = '\0';
cout << "\nСообщение от сервера: " << buffer << "\n";
}
else if (result == 0) {
cout << "Connection closed by server.\n";
running = false;
break;
}
else {
cerr << "Receive failed: " << WSAGetLastError() << "\n";
running = false;
break;
}
}
}
public:
TcpClient() : connectSocket(INVALID_SOCKET), running(true) {}
~TcpClient() {
if (connectSocket != INVALID_SOCKET) {
closesocket(connectSocket);
}
WSACleanup();
}
bool start(const char* ip = "localhost", const char* port = DEFAULT_PORT) {
if (!initializeWinsock()) return false;
if (!createAndConnectSocket(ip, port)) return false;
thread senderThread(&TcpClient::sender, this);
thread receiverThread(&TcpClient::receiver, this);
senderThread.join();
receiverThread.join();
return true;
}
};
int main() {
setlocale(0, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
system("title CLIENT SIDE");
TcpClient client;
if (!client.start()) {
cerr << "Failed to start client.\n";
return 1;
}
}
@sunmeat
Copy link
Author

sunmeat commented Mar 15, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment