Advertisement
VladimirKostovsky

Osi_lab3_server

Dec 5th, 2023 (edited)
952
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 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.     serverInfo.sin_port = htons(2003);
  67.  
  68.     retVal = bind(serverSock, (LPSOCKADDR)&serverInfo, sizeof(serverInfo));
  69.     if (retVal == SOCKET_ERROR) {
  70.         cout << "Не удается связать сокет с адресом" << endl;
  71.         closesocket(serverSock);
  72.         WSACleanup();
  73.         return 1;
  74.     }
  75.  
  76.     retVal = listen(serverSock, SOMAXCONN);
  77.     if (retVal == SOCKET_ERROR) {
  78.         cout << "Не удается установить прослушивание" << endl;
  79.         closesocket(serverSock);
  80.         WSACleanup();
  81.         return 1;
  82.     }
  83.  
  84.     cout << "Ожидание подключения клиентов..." << endl;
  85.  
  86.     while (true) {
  87.         SOCKADDR_IN clientAddr;
  88.         int addrSize = sizeof(clientAddr);
  89.         SOCKET clientSock = accept(serverSock, (sockaddr*)&clientAddr, &addrSize);
  90.  
  91.         if (clientSock == INVALID_SOCKET) {
  92.             cout << "Ошибка при подключении клиента" << endl;
  93.             closesocket(serverSock);
  94.             WSACleanup();
  95.             return 1;
  96.         }
  97.  
  98.         cout << "Клиент подключен" << endl;
  99.  
  100.         char nameBuffer[BUFFER_SIZE] = { '\0' };
  101.         retVal = recv(clientSock, nameBuffer, sizeof(nameBuffer), 0);
  102.         if (retVal == SOCKET_ERROR) {
  103.             cout << "Ошибка при получении имени клиента" << endl;
  104.             closesocket(clientSock);
  105.             closesocket(serverSock);
  106.             WSACleanup();
  107.             return 1;
  108.         }
  109.  
  110.         string clientName(nameBuffer);
  111.         cout << "Клиент '" << clientName << "' присоединился" << endl;
  112.  
  113.         // Добавить нового клиента в список
  114.         clients.push_back({ clientSock, clientName });
  115.  
  116.         // Запустить поток для обработки сообщений от клиента
  117.         thread(receiveMessages, clients.back()).detach();
  118.     }
  119.  
  120.     closesocket(serverSock);
  121.     WSACleanup();
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement