Skip to content

Instantly share code, notes, and snippets.

@Vinnik67
Created March 28, 2026 10:10
Show Gist options
  • Select an option

  • Save Vinnik67/a43d7508d5e5be6d994e3dbeb8e9bd0f to your computer and use it in GitHub Desktop.

Select an option

Save Vinnik67/a43d7508d5e5be6d994e3dbeb8e9bd0f to your computer and use it in GitHub Desktop.
#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;
}
#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