Advertisement
VladimirKostovsky

Osi_lab3_serverWin_to_ethernet

Dec 18th, 2023
833
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.66 KB | None | 0 0
  1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  2. #include <iostream>
  3. #include <thread>
  4. #include <string>
  5. #include <vector>
  6. #include <winsock2.h>
  7.  
  8. using namespace std;
  9.  
  10. const int BUFFER_SIZE = 1024;
  11.  
  12. struct ClientInfo {
  13.     SOCKET socket;
  14.     string name;
  15. };
  16.  
  17. vector<ClientInfo> clients;
  18.  
  19. void receiveMessages(ClientInfo client) {
  20.     char buffer[BUFFER_SIZE] = { '\0' };
  21.     int retVal;
  22.     while (true) {
  23.         retVal = recv(client.socket, buffer, sizeof(buffer), 0);
  24.         if (retVal == SOCKET_ERROR) {
  25.             cout << "Соединение с клиентом " << client.name << " разорвано" << endl;
  26.             closesocket(client.socket);
  27.  
  28.             // Удалить отключенного клиента из списка
  29.             clients.erase(remove_if(clients.begin(), clients.end(),
  30.                 [&](const ClientInfo& c) { return c.socket == client.socket; }), clients.end());
  31.  
  32.             return;
  33.         }
  34.  
  35.         // Отправить сообщение всем клиентам
  36.         for (const auto& otherClient : clients) {
  37.             if (otherClient.socket != client.socket) {
  38.                 string message = client.name + ": " + buffer;
  39.                 send(otherClient.socket, message.c_str(), message.size(), 0);
  40.             }
  41.         }
  42.  
  43.         cout << client.name << ": " << buffer << endl;
  44.     }
  45. }
  46.  
  47. int main() {
  48.     SetConsoleCP(1251);
  49.     SetConsoleOutputCP(1251);
  50.  
  51.     int retVal = 0;
  52.     WORD ver = MAKEWORD(2, 2);
  53.     WSADATA wsaData;
  54.     WSAStartup(ver, &wsaData);
  55.  
  56.     SOCKET serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  57.     if (serverSock == SOCKET_ERROR) {
  58.         cout << "Не удается создать сокет" << endl;
  59.         WSACleanup();
  60.         return 1;
  61.     }
  62.  
  63.     SOCKADDR_IN serverInfo;
  64.     serverInfo.sin_family = PF_INET;
  65.     serverInfo.sin_addr.s_addr = INADDR_ANY;
  66.  
  67.     // Ввод номера прослушиваемого порта с клавиатуры
  68.     unsigned short port;
  69.     cout << "Введите номер прослушиваемого порта: ";
  70.     cin >> port;
  71.     cin.ignore(); // очистка потока ввода
  72.  
  73.     serverInfo.sin_port = htons(port);
  74.  
  75.     retVal = bind(serverSock, (LPSOCKADDR)&serverInfo, sizeof(serverInfo));
  76.     if (retVal == SOCKET_ERROR) {
  77.         cout << "Не удается связать сокет с адресом" << endl;
  78.         closesocket(serverSock);
  79.         WSACleanup();
  80.         return 1;
  81.     }
  82.  
  83.     // Выводим IP-адрес компьютера
  84.     char hostname[256];
  85.     gethostname(hostname, sizeof(hostname));
  86.     hostent* host_info = gethostbyname(hostname);
  87.     char* ip = inet_ntoa(*(struct in_addr*)*host_info->h_addr_list);
  88.     cout << "IP-адрес сервера: " << ip << endl;
  89.  
  90.     retVal = listen(serverSock, SOMAXCONN);
  91.     if (retVal == SOCKET_ERROR) {
  92.         cout << "Не удается установить прослушивание" << endl;
  93.         closesocket(serverSock);
  94.         WSACleanup();
  95.         return 1;
  96.     }
  97.  
  98.     cout << "Ожидание подключения клиентов..." << endl;
  99.  
  100.     while (true) {
  101.         SOCKADDR_IN clientAddr;
  102.         int addrSize = sizeof(clientAddr);
  103.         SOCKET clientSock = accept(serverSock, (sockaddr*)&clientAddr, &addrSize);
  104.  
  105.         if (clientSock == INVALID_SOCKET) {
  106.             cout << "Ошибка при подключении клиента" << endl;
  107.             closesocket(serverSock);
  108.             WSACleanup();
  109.             return 1;
  110.         }
  111.  
  112.         // Выводим IP-адрес и порт подключившегося клиента
  113.         cout << "Клиент подключен. IP: " << inet_ntoa(clientAddr.sin_addr) << ", Порт: " << ntohs(clientAddr.sin_port) << endl;
  114.  
  115.         char nameBuffer[BUFFER_SIZE] = { '\0' };
  116.         retVal = recv(clientSock, nameBuffer, sizeof(nameBuffer), 0);
  117.         if (retVal == SOCKET_ERROR) {
  118.             cout << "Ошибка при получении имени клиента" << endl;
  119.             closesocket(clientSock);
  120.             closesocket(serverSock);
  121.             WSACleanup();
  122.             return 1;
  123.         }
  124.  
  125.         string clientName(nameBuffer);
  126.         cout << "Клиент '" << clientName << "' присоединился" << endl;
  127.  
  128.         // Добавить нового клиента в список
  129.         clients.push_back({ clientSock, clientName });
  130.  
  131.         // Запустить поток для обработки сообщений от клиента
  132.         thread(receiveMessages, clients.back()).detach();
  133.     }
  134.  
  135.     closesocket(serverSock);
  136.     WSACleanup();
  137.     return 0;
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement