Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created March 15, 2025 15:46
Show Gist options
  • Save sunmeat/d37480aef89b9d7eb294cecd0e30ff00 to your computer and use it in GitHub Desktop.
Save sunmeat/d37480aef89b9d7eb294cecd0e30ff00 to your computer and use it in GitHub Desktop.
OOP TCP + OOP-threads: SERVER SIDE
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <windows.h>
#include <ws2tcpip.h>
#include <thread>
#include <memory>
#include <string>
using namespace std;
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define PAUSE 1
class TcpServer {
private:
SOCKET listenSocket = INVALID_SOCKET;
SOCKET clientSocket = INVALID_SOCKET;
addrinfo* result = nullptr;
public:
TcpServer() = default;
~TcpServer() {
if (clientSocket != INVALID_SOCKET) closesocket(clientSocket);
if (listenSocket != INVALID_SOCKET) closesocket(listenSocket);
if (result) freeaddrinfo(result);
WSACleanup();
}
bool initialize() {
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
cerr << "WSAStartup failed: " << iResult << "\n";
return false;
}
addrinfo hints{};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
cerr << "getaddrinfo failed: " << iResult << "\n";
return false;
}
listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listenSocket == INVALID_SOCKET) {
cerr << "Error creating socket: " << WSAGetLastError() << "\n";
return false;
}
iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
cerr << "Bind failed: " << WSAGetLastError() << "\n";
return false;
}
iResult = listen(listenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
cerr << "Listen failed: " << WSAGetLastError() << "\n";
return false;
}
clientSocket = accept(listenSocket, NULL, NULL);
if (clientSocket == INVALID_SOCKET) {
cerr << "Accept failed: " << WSAGetLastError() << "\n";
return false;
}
return true;
}
void sender() {
while (true) {
string message;
cout << "Введите сообщение для клиента: ";
getline(cin, message);
int iSendResult = send(clientSocket, message.c_str(), message.length(), 0);
if (iSendResult == SOCKET_ERROR) {
cerr << "Send failed: " << WSAGetLastError() << "\n";
return;
}
Sleep(PAUSE);
}
}
void receiver() {
char recvbuf[DEFAULT_BUFLEN];
while (true) {
int iResult = recv(clientSocket, recvbuf, DEFAULT_BUFLEN, 0);
if (iResult > 0) {
recvbuf[iResult] = '\0';
cout << "\nКлиент отправил: " << recvbuf << "\n";
}
Sleep(PAUSE);
}
}
void run() {
thread sendThread(&TcpServer::sender, this);
thread receiveThread(&TcpServer::receiver, this);
sendThread.join();
receiveThread.join();
}
};
int main() {
setlocale(0, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
system("title SERVER SIDE");
// умный указатель, который владеет объектом и гарантирует, что объект будет удалён автоматически, когда указатель уничтожается
auto server = make_unique<TcpServer>();
if (!server->initialize()) {
cerr << "Failed to initialize server.\n";
return 1;
}
server->run();
}
@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