Created
March 28, 2026 10:10
-
-
Save Vinnik67/a43d7508d5e5be6d994e3dbeb8e9bd0f to your computer and use it in GitHub Desktop.
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 <ws2tcpip.h> | |
| #include <windows.h> | |
| #include <iostream> | |
| #include <string> | |
| #include <queue> | |
| #include <map> | |
| #include <chrono> | |
| #include <thread> | |
| using namespace std; | |
| #pragma comment(lib, "Ws2_32.lib") | |
| #define DEFAULT_BUFLEN 4096 | |
| #define DEFAULT_PORT "8888" | |
| SOCKET server_socket; | |
| // структура замовлення | |
| struct Order { | |
| sockaddr_in client; | |
| string dish; | |
| chrono::system_clock::time_point timeReceived; | |
| }; | |
| // черга замовлень | |
| queue<Order> orderQueue; | |
| // меню ресторану | |
| map<string,int> menu = { | |
| {"borsch",5}, {"salad",2}, {"steak",7}, {"pizza",4}, {"soup",3}, | |
| {"pasta",6}, {"burger",4}, {"sushi",5}, {"cake",3}, {"tea",1} | |
| }; | |
| // функція "шеф-кухаря" | |
| void chefWorker() { | |
| while(true) { | |
| if(!orderQueue.empty()) { | |
| Order order = orderQueue.front(); | |
| orderQueue.pop(); | |
| auto waitTime = chrono::system_clock::now() - order.timeReceived; | |
| cout << "[LOG] Замовлення: " << order.dish | |
| << " | Очікування: " << chrono::duration_cast<chrono::seconds>(waitTime).count() | |
| << " сек." << endl; | |
| int cookTime = menu[order.dish]; | |
| this_thread::sleep_for(chrono::seconds(cookTime)); | |
| string msg = "Ваша їжа готова, смачного!\n"; | |
| sendto(server_socket, msg.c_str(), msg.size(), 0, | |
| (sockaddr*)&order.client, sizeof(order.client)); | |
| } | |
| else { | |
| this_thread::sleep_for(chrono::milliseconds(100)); | |
| } | |
| } | |
| } | |
| int main() { | |
| setlocale(0, ""); | |
| system("title UDP СЕРВЕРНА СТОРОНА"); | |
| WSADATA wsaData; | |
| int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); | |
| if (iResult != 0) { | |
| printf("Помилка ініціалізації Winsock: %d\n", iResult); | |
| return 1; | |
| } | |
| server_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
| if (server_socket == INVALID_SOCKET) { | |
| printf("Помилка створення сокета: %ld\n", WSAGetLastError()); | |
| WSACleanup(); | |
| return 2; | |
| } | |
| sockaddr_in server_addr; | |
| server_addr.sin_family = AF_INET; | |
| server_addr.sin_addr.s_addr = INADDR_ANY; | |
| server_addr.sin_port = htons(8888); | |
| if (bind(server_socket, (sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) { | |
| printf("Помилка прив'язки: %d\n", WSAGetLastError()); | |
| closesocket(server_socket); | |
| WSACleanup(); | |
| return 3; | |
| } | |
| cout << "Сервер запущено. Очікування замовлень..." << endl; | |
| thread chef(chefWorker); | |
| chef.detach(); | |
| char client_message[DEFAULT_BUFLEN]; | |
| sockaddr_in client_addr; | |
| int addrlen = sizeof(client_addr); | |
| while(true) { | |
| int result = recvfrom(server_socket, client_message, DEFAULT_BUFLEN, 0, | |
| (sockaddr*)&client_addr, &addrlen); | |
| if (result == SOCKET_ERROR) { | |
| printf("Помилка recvfrom: %d\n", WSAGetLastError()); | |
| continue; | |
| } | |
| client_message[result] = '\0'; | |
| string dish(client_message); | |
| cout << "[LOG] Нове замовлення від ip: " << inet_ntoa(client_addr.sin_addr) | |
| << ", порт: " << ntohs(client_addr.sin_port) | |
| << " | страва: " << dish << endl; | |
| // перевірка чи страва є в меню | |
| if(menu.find(dish) == menu.end()) { | |
| string msg = "Такої страви немає у меню!\n"; | |
| sendto(server_socket, msg.c_str(), msg.size(), 0, | |
| (sockaddr*)&client_addr, addrlen); | |
| continue; | |
| } | |
| // додати замовлення у чергу | |
| Order order{client_addr, dish, chrono::system_clock::now()}; | |
| orderQueue.push(order); | |
| } | |
| closesocket(server_socket); | |
| WSACleanup(); | |
| 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
| #include <winsock2.h> | |
| #include <iostream> | |
| #include <vector> | |
| #include <string> | |
| using namespace std; | |
| #define MAX_CLIENTS 10 | |
| #define DEFAULT_BUFLEN 4096 | |
| #pragma comment(lib, "ws2_32.lib") | |
| #pragma warning(disable:4996) | |
| SOCKET server_socket; | |
| vector<string> history; // історія повідомлень | |
| vector<sockaddr_in> clients; // список адрес клієнтів | |
| int main() { | |
| setlocale(0, ""); | |
| system("title UDP СЕРВЕРНА СТОРОНА"); | |
| puts("запуск сервера... виконано."); | |
| WSADATA wsa; | |
| // ініціалізація Winsock | |
| if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { | |
| printf("помилка ініціалізації. код помилки: %d", WSAGetLastError()); | |
| return 1; | |
| } | |
| // створення UDP-сокета | |
| if ((server_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { | |
| printf("не вдалося створити сокет: %d", WSAGetLastError()); | |
| return 2; | |
| } | |
| sockaddr_in server; | |
| server.sin_family = AF_INET; | |
| server.sin_addr.s_addr = INADDR_ANY; | |
| server.sin_port = htons(8888); | |
| // прив'язка сокета до адреси та порту | |
| if (bind(server_socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { | |
| printf("помилка прив'язки з кодом: %d", WSAGetLastError()); | |
| closesocket(server_socket); | |
| WSACleanup(); | |
| return 3; | |
| } | |
| puts("сервер очікує вхідні UDP-повідомлення...\nзапустіть один або кілька клієнтів."); | |
| fd_set readfds; | |
| char client_message[DEFAULT_BUFLEN]; | |
| sockaddr_in client_addr; | |
| int addrlen = sizeof(client_addr); | |
| while (true) { | |
| // очищення набору сокетів | |
| FD_ZERO(&readfds); | |
| FD_SET(server_socket, &readfds); | |
| // очікування активності на сокеті | |
| if (select(0, &readfds, NULL, NULL, NULL) == SOCKET_ERROR) { | |
| printf("помилка функції select з кодом: %d", WSAGetLastError()); | |
| closesocket(server_socket); | |
| WSACleanup(); | |
| return 4; | |
| } | |
| if (FD_ISSET(server_socket, &readfds)) { | |
| // отримання повідомлення від клієнта | |
| int client_message_length = recvfrom(server_socket, client_message, DEFAULT_BUFLEN, 0, (sockaddr*)&client_addr, &addrlen); | |
| if (client_message_length < 0) { | |
| printf("помилка recvfrom з кодом: %d", WSAGetLastError()); | |
| continue; | |
| } | |
| client_message[client_message_length] = '\0'; | |
| printf("отримано повідомлення від ip: %s, порт: %d: %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), client_message); | |
| // перевірка, чи є клієнт у списку | |
| bool client_exists = false; | |
| for (const auto& addr : clients) { | |
| if (addr.sin_addr.s_addr == client_addr.sin_addr.s_addr && addr.sin_port == client_addr.sin_port) { | |
| client_exists = true; | |
| break; | |
| } | |
| } | |
| // додавання нового клієнта та надсилання історії | |
| if (!client_exists && clients.size() < MAX_CLIENTS) { | |
| clients.push_back(client_addr); | |
| printf("новий клієнт додано. всього клієнтів: %zu\n", clients.size()); | |
| for (const auto& msg : history) { | |
| sendto(server_socket, msg.c_str(), msg.size(), 0, (sockaddr*)&client_addr, addrlen); | |
| } | |
| } | |
| string check_exit = client_message; | |
| // обробка відключення клієнта | |
| if (check_exit == "off") { | |
| printf("клієнт з ip: %s, порт: %d відключився\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); | |
| for (auto it = clients.begin(); it != clients.end(); ++it) { | |
| if (it->sin_addr.s_addr == client_addr.sin_addr.s_addr && it->sin_port == client_addr.sin_port) { | |
| clients.erase(it); | |
| break; | |
| } | |
| } | |
| } | |
| else { | |
| // збереження повідомлення в історію | |
| string temp = client_message; | |
| history.push_back(temp); | |
| // розсилка повідомлення всім клієнтам, крім відправника | |
| for (const auto& addr : clients) { | |
| if (!(addr.sin_addr.s_addr == client_addr.sin_addr.s_addr && addr.sin_port == client_addr.sin_port)) { | |
| sendto(server_socket, client_message, client_message_length, 0, (sockaddr*)&addr, sizeof(addr)); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| closesocket(server_socket); | |
| WSACleanup(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment