Last active
October 1, 2025 16:04
-
-
Save sunmeat/d37480aef89b9d7eb294cecd0e30ff00 to your computer and use it in GitHub Desktop.
OOP TCP + OOP-threads: SERVER SIDE
This file contains hidden or 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
| #define WIN32_LEAN_AND_MEAN | |
| #include <iostream> | |
| #include <windows.h> | |
| #include <ws2tcpip.h> | |
| #include <thread> | |
| #include <string> | |
| using namespace std; | |
| #pragma comment (lib, "Ws2_32.lib") | |
| #define DEFAULT_BUFLEN 512 | |
| #define DEFAULT_PORT "27015" | |
| #define PAUSE 1 | |
| class TcpServer { | |
| SOCKET listenSocket = INVALID_SOCKET; | |
| SOCKET clientSocket = INVALID_SOCKET; | |
| addrinfo* result = nullptr; | |
| public: | |
| ~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(); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CLIENT SIDE: https://gist.github.com/sunmeat/3eb4334238569d07aa8495fc567fef8f