Created
February 26, 2026 07:30
-
-
Save Marie-zaj/15b175f8728b79636be2bc122e7479d7 to your computer and use it in GitHub Desktop.
Fgfhfjfjfjf
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 <winsock2.h> | |
| #include <ws2tcpip.h> | |
| using namespace std; | |
| // потрібно зв'язати з Ws2_32.lib, Mswsock.lib та Advapi32.lib | |
| #pragma comment (lib, "Ws2_32.lib") | |
| #pragma comment (lib, "Mswsock.lib") | |
| #pragma comment (lib, "AdvApi32.lib") | |
| #define DEFAULT_BUFLEN 512 | |
| #define DEFAULT_PORT "27015" | |
| #define PAUSE 1000 | |
| int main(int argc, char** argv) // ім'я сервера при бажанні можна буде вказати через параметри командного рядка | |
| { | |
| // я намагався максимально спростити запуск клієнтського додатку, тому кількість параметрів командного рядка не перевіряється! | |
| // перевірка параметрів якщо треба | |
| // if (argc != 2) { | |
| // printf("usage: %s server-name\n", argv[0]); | |
| // return 10; | |
| // } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| setlocale(0, "Ukrainian"); | |
| system("title CLIENT SIDE"); | |
| cout << "процес клiєнта запущено!\n"; | |
| Sleep(PAUSE); | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // iніціалізація Winsock | |
| WSADATA wsaData; | |
| int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); | |
| if (iResult != 0) { | |
| cout << "WSAStartup не вдалося з помилкою: " << iResult << "\n"; | |
| return 11; | |
| } | |
| else { | |
| cout << "пiдключення до Winsock.dll пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| addrinfo hints; | |
| ZeroMemory(&hints, sizeof(hints)); | |
| hints.ai_family = AF_UNSPEC; | |
| hints.ai_socktype = SOCK_STREAM; | |
| hints.ai_protocol = IPPROTO_TCP; | |
| // отримання адреси сервера та порту | |
| const char* ip = "localhost"; // за замовчуванням, обидва додатки, і клієнт, і сервер, працюють на одній і тій самій машині | |
| // iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); // раскоментувати, якщо потрібно буде зчитувати ім'я сервера з командного рядка | |
| addrinfo* result = NULL; | |
| iResult = getaddrinfo(ip, DEFAULT_PORT, &hints, &result); | |
| if (iResult != 0) { | |
| cout << "getaddrinfo не вдалося з помилкою: " << iResult << "\n"; | |
| WSACleanup(); | |
| return 12; | |
| } | |
| else { | |
| cout << "отримання адреси та порту клiєнта пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // спроба підключення до адреси до успіху | |
| SOCKET ConnectSocket = INVALID_SOCKET; | |
| for (addrinfo* ptr = result; ptr != NULL; ptr = ptr->ai_next) { // серверів може бути кілька, тому не завадить цикл | |
| // створення SOCKET для підключення до сервера | |
| ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); | |
| if (ConnectSocket == INVALID_SOCKET) { | |
| cout << "socket не вдалося створити з помилкою: " << WSAGetLastError() << "\n"; | |
| WSACleanup(); | |
| return 13; | |
| } | |
| // підключення до сервера | |
| iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); | |
| if (iResult == SOCKET_ERROR) { | |
| closesocket(ConnectSocket); | |
| ConnectSocket = INVALID_SOCKET; | |
| continue; | |
| } | |
| cout << "створення сокета на клiєнтi пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| break; | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| freeaddrinfo(result); | |
| if (ConnectSocket == INVALID_SOCKET) { | |
| cout << "неможливо пiдключитися до сервера. перевiрте, чи запущено процес сервера!\n"; | |
| WSACleanup(); | |
| return 14; | |
| } | |
| else { | |
| cout << "пiдключення до сервера пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // відправка початкового буфера | |
| const char* message = "hello from client!"; | |
| iResult = send(ConnectSocket, message, (int)strlen(message), 0); | |
| if (iResult == SOCKET_ERROR) { | |
| cout << "send не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| closesocket(ConnectSocket); | |
| WSACleanup(); | |
| return 15; | |
| } | |
| else { | |
| cout << "данi успiшно вiдправлено на сервер: " << message << "\n"; | |
| cout << "байтiв вiдправлено з клiєнта: " << iResult << "\n"; | |
| Sleep(PAUSE); | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // закриття з'єднання, оскільки більше даних не буде відправлено | |
| iResult = shutdown(ConnectSocket, SD_SEND); | |
| if (iResult == SOCKET_ERROR) { | |
| cout << "shutdown не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| closesocket(ConnectSocket); | |
| WSACleanup(); | |
| return 16; | |
| } | |
| else { | |
| cout << "процес клiєнта iнiцiює закриття з'єднання з сервером.\n"; | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // отримання даних до закриття з'єднання зі сторони сервера | |
| char answer[DEFAULT_BUFLEN]; | |
| do { | |
| iResult = recv(ConnectSocket, answer, DEFAULT_BUFLEN, 0); | |
| answer[iResult] = '\0'; | |
| if (iResult > 0) { | |
| cout << "процес сервера надiслав вiдповiдь: " << answer << "\n"; | |
| cout << "байтiв отримано: " << iResult << "\n"; | |
| } | |
| else if (iResult == 0) | |
| cout << "з'єднання з сервером закрито.\n"; | |
| else | |
| cout << "recv не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| } while (iResult > 0); | |
| // очистка | |
| closesocket(ConnectSocket); | |
| WSACleanup(); | |
| cout << "процес клiєнта завершує свою роботу!\n"; | |
| return 0; | |
| } |
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 // для прискорення процесу збірки: https://stackoverflow.com/questions/11040133/what-does-defining-win32-lean-and-mean-exclude-exactly | |
| #include <iostream> | |
| #include <ws2tcpip.h> // тип WSADATA, функції WSAStartup, WSACleanup та багато чого іншого | |
| using namespace std; | |
| // реалізація бібліотеки Winsock 2 DLL | |
| #pragma comment (lib, "Ws2_32.lib") | |
| // #pragma comment (lib, "Mswsock.lib") | |
| #define DEFAULT_BUFLEN 512 | |
| #define DEFAULT_PORT "27015" // порт — це логічна конструкція, яка ідентифікує конкретний процес або тип мережевої служби - https://en.wikipedia.org/wiki/Port_(computer_networking) | |
| #define PAUSE 1000 | |
| int main() | |
| { | |
| setlocale(0, ""); | |
| system("title SERVER SIDE"); | |
| cout << "процес сервера запущено!\n"; | |
| Sleep(PAUSE); | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // ініціалізація Winsock | |
| WSADATA wsaData; // Структура WSADATA містить інформацію про реалізацію Windows Sockets: https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-wsadata | |
| int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); // Функція WSAStartup ініціює використання бібліотеки Winsock DLL процесом: https://firststeps.ru/mfc/net/socket/r.php?2 | |
| if (iResult != 0) { | |
| cout << "WSAStartup не вдалося з помилкою: " << iResult << "\n"; | |
| cout << "пiдключення Winsock.dll пройшло з помилкою!\n"; | |
| return 1; | |
| } | |
| else { | |
| cout << "пiдключення Winsock.dll пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| struct addrinfo hints {}; // структура addrinfo використовується функцією getaddrinfo для зберігання інформації про адресу хоста: https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoa | |
| hints.ai_family = AF_INET; // адреса сімейства протоколу Інтернету версії 4 (IPv4) | |
| hints.ai_socktype = SOCK_STREAM; // забезпечує послідовні, надійні, двосторонні, засновані на з'єднанні потоки байтів з механізмом передачі даних | |
| hints.ai_protocol = IPPROTO_TCP; // протокол передачі управління (TCP). Це можливе значення, коли член ai_family є AF_INET або AF_INET6, а член ai_socktype — SOCK_STREAM | |
| hints.ai_flags = AI_PASSIVE; // адреса сокета буде використовуватися в виклику функції "bind" | |
| // визначення адреси та порту сервера | |
| struct addrinfo* result = NULL; | |
| iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); | |
| if (iResult != 0) { | |
| cout << "getaddrinfo не вдалося з помилкою: " << iResult << "\n"; | |
| cout << "отримання адреси та порту сервера пройшло з помилкою!\n"; | |
| WSACleanup(); // функція WSACleanup завершує використання бібліотеки Winsock 2 DLL (Ws2_32.dll): https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsacleanup | |
| return 2; | |
| } | |
| else { | |
| cout << "отримання адреси та порту сервера пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // створення сокету для підключення до сервера | |
| SOCKET ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); | |
| if (ListenSocket == -1) { | |
| cout << "socket не вдалося створити з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "створення сокета пройшло з помилкою!\n"; | |
| freeaddrinfo(result); | |
| WSACleanup(); | |
| return 3; | |
| } | |
| else { | |
| cout << "створення сокета на серверi пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // налаштування сокета для прослуховування | |
| iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); // Функція bind асоціює локальну адресу з сокетом: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind | |
| if (iResult == -1) { | |
| cout << "bind не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "вбудова сокета по IP-адресi пройшла з помилкою!\n"; | |
| freeaddrinfo(result); | |
| closesocket(ListenSocket); | |
| WSACleanup(); | |
| return 4; | |
| } | |
| else { | |
| cout << "впровадження сокету по IP-адресi пройшло успiшно!\n"; | |
| Sleep(PAUSE); | |
| } | |
| freeaddrinfo(result); | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| iResult = listen(ListenSocket, SOMAXCONN); // функція listen ставить сокет у стан, коли він чекає вхідне підключення: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen | |
| if (iResult == -1) { | |
| cout << "listen не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "прослуховування iнформації вiд клiєнта не почалося. щось пiшло не так!\n"; | |
| closesocket(ListenSocket); | |
| WSACleanup(); | |
| return 5; | |
| } | |
| else { | |
| cout << "починається прослуховування iнформацiї вiд клiєнта. будь ласка, запустiть клiєнтську програму! (client.exe)\n"; | |
| // тут можна було б запустити якийсь прелоадер в окремому потоці | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // прийом сокета клієнта | |
| SOCKET ClientSocket = accept(ListenSocket, NULL, NULL); // Функція accept дозволяє прийняти вхідне підключення на сокет: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept | |
| if (ClientSocket == INVALID_SOCKET) { | |
| cout << "accept не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "пiдключення з клiєнтською програмою не встановлено! сумно, сумно аж за край ((\n"; | |
| closesocket(ListenSocket); | |
| WSACleanup(); | |
| return 6; | |
| } | |
| else { | |
| cout << "пiдключення з клiєнтською програмою встановлено успiшно!\n"; | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // більше не потрібно зберігати сокет сервера | |
| closesocket(ListenSocket); | |
| // отримання даних до того моменту, поки з'єднання не буде завершено | |
| do { | |
| char message[DEFAULT_BUFLEN] = { 0 }; | |
| iResult = recv(ClientSocket, message, DEFAULT_BUFLEN, 0); // функція recv використовується для читання вхідних даних: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv | |
| message[iResult] = '\0'; | |
| if (iResult > 0) { | |
| cout << "процес клiєнта надiслав повiдомлення: " << message << "\n"; | |
| Sleep(PAUSE); | |
| cout << "байтiв отримано: " << iResult << "\n"; | |
| Sleep(PAUSE); | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // відправка відповіді назад відправнику | |
| const char* answer = "and hello from server!"; | |
| cout << "процес сервера вiдправляє вiдповiдь: " << answer << "\n"; | |
| int iSendResult = send(ClientSocket, answer, strlen(answer), 0); // функція send відправляє дані на підключений сокет: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send | |
| Sleep(PAUSE); | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| if (iSendResult == SOCKET_ERROR) { | |
| cout << "send не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "упс, вiдправка (send) вiдповiдного повiдомлення не вiдбулася ((\n"; | |
| closesocket(ClientSocket); | |
| WSACleanup(); | |
| return 7; | |
| } | |
| else { | |
| cout << "байтiв вiдправлено: " << iSendResult << "\n"; | |
| Sleep(PAUSE); | |
| } | |
| } | |
| else if (iResult == 0) { | |
| cout << "з'єднання закривається...\n"; | |
| Sleep(PAUSE); | |
| } | |
| else { | |
| cout << "recv не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "упс, отримання (recv) вiдповiдного повiдомлення не вiдбулося ((\n"; | |
| closesocket(ClientSocket); | |
| WSACleanup(); | |
| return 8; | |
| } | |
| } while (iResult > 0); | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // закриття з'єднання, оскільки роботу завершено | |
| iResult = shutdown(ClientSocket, SD_SEND); // функція shutdown вимикає надсилання або отримання даних на сокеті: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown | |
| if (iResult == SOCKET_ERROR) { | |
| cout << "shutdown не вдалося з помилкою: " << WSAGetLastError() << "\n"; | |
| cout << "упс, розрив з'єднання (shutdown) видав помилку ((\n"; | |
| closesocket(ClientSocket); | |
| WSACleanup(); | |
| return 9; | |
| } | |
| else { | |
| cout << "процес сервера припиняє свою роботу! до нових запускiв! :)\n"; | |
| } | |
| // вивільнення памяті | |
| closesocket(ClientSocket); | |
| WSACleanup(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment