Endil

cn-lab2-server-mt

Sep 21st, 2015
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | None | 0 0
  1. // cn-lab2-server-mt.cpp: определяет точку входа для консольного приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <winsock2.h>
  6. #include <iostream>
  7. #include <sstream>
  8. #include <thread>
  9. #include <vector>
  10. #include <regex>
  11. #include <map>
  12.  
  13. #pragma comment(lib, "ws2_32.lib")
  14.  
  15. using namespace std;
  16.  
  17. vector<thread> requests;
  18. map<sockaddr_in, int> clients;
  19.  
  20. bool operator< (const sockaddr_in addr_left, const sockaddr_in addr_right) {
  21.     string left = inet_ntoa(addr_left.sin_addr) + ':' + addr_left.sin_port;
  22.     string right = inet_ntoa(addr_right.sin_addr) + ':' + addr_right.sin_port;
  23.     return left < right;
  24. }
  25.  
  26. int request_process(const int request_id, const SOCKET sock, const sockaddr_in client_addr, const int client_addr_size, string request) {
  27.     regex triangle_pattern(" *\\d+ +\\d+ +\\d+ *");
  28.     if (!regex_match(request, triangle_pattern)) {
  29.         sendto(sock, "Invalid input", sizeof("Invalid input"), 0, (sockaddr *)&client_addr, client_addr_size);
  30.         cout << "Answer " << request_id << " sent" << endl;
  31.         return 0;
  32.     }
  33.     int a, b, c;
  34.     stringstream ss;
  35.     ss << request;
  36.     ss >> a >> b >> c;
  37.     string triangle_exist = "false";
  38.     if ((a < b + c) && (b < a + c) && (c < a + b))
  39.         triangle_exist = "true";
  40.     sendto(sock, triangle_exist.c_str(), triangle_exist.length(), 0, (sockaddr *)&client_addr, client_addr_size);
  41.     cout << "Answer " << request_id << " sent" << endl;
  42.     return 0;
  43. }
  44.  
  45. int port_listen(const SOCKET &sock) {
  46.     for (int request_id = 1, client_id = 1;;) {
  47.         sockaddr_in client_addr;
  48.         int client_addr_size = sizeof(client_addr);
  49.         char recv_buff[1024];
  50.         int len = recvfrom(sock, &recv_buff[0], sizeof(recv_buff) - 1, 0, (sockaddr *)&client_addr, &client_addr_size);
  51.         if (len < 0)
  52.             return 1;
  53.         recv_buff[len] = '\0';
  54.         string request = recv_buff;
  55.         if (request == "&new_client") {
  56.             clients.insert(pair<sockaddr_in, int>(client_addr, client_id));
  57.             cout << "New client #" << client_id << " was opened" << endl;
  58.             client_id++;
  59.             continue;
  60.         }
  61.         if (request == "&client_exit") {
  62.             cout << "Client #" << clients.at(client_addr) << " was closed" << endl;
  63.             clients.erase(client_addr);
  64.             continue;
  65.         }
  66.         cout << "Request " << request_id << " received" << endl;
  67.         requests.push_back(thread(request_process, request_id, sock, client_addr, client_addr_size, request));
  68.         request_id++;
  69.     }
  70.     return 0;
  71. }
  72.  
  73. int main()
  74. {
  75.     cout << "cn-lab2 var10 server start" << endl;
  76.     WSAData wsadata;
  77.     WSAStartup(0x0202, &wsadata);
  78.     cout << "WinSock2 initialized" << endl;
  79.     SOCKET sock;
  80.     sock = socket(AF_INET, SOCK_DGRAM, 0);
  81.     if (sock == INVALID_SOCKET) {
  82.         cout << "Create socket error " << WSAGetLastError() << endl;
  83.         WSACleanup();
  84.         return 1;
  85.     }
  86.     cout << "Socket created successfully" << endl;
  87.     sockaddr_in local_addr;
  88.     local_addr.sin_family = AF_INET;
  89.     local_addr.sin_addr.S_un.S_addr = 0;
  90.     local_addr.sin_port = htons(5002);
  91.     if (::bind(sock, (sockaddr *)&local_addr, sizeof(local_addr))) {
  92.         cout << "Error bind " << WSAGetLastError() << endl;
  93.         closesocket(sock);
  94.         WSACleanup();
  95.         return 2;
  96.     }
  97.     cout << "Bound successful" << endl;
  98.     thread listen(port_listen, sock);
  99.     string s;
  100.     do {
  101.         cin >> s;
  102.     } while (s != "stop");
  103.     for (auto client : clients)
  104.         sendto(sock, "&server_stop", sizeof("&server_stop"), 0, (sockaddr *)&client.first, sizeof(client.first));
  105.     closesocket(sock);
  106.     if (listen.joinable())
  107.         listen.join();
  108.     for (int i = 0; i < requests.size(); i++) {
  109.         if (requests[i].joinable())
  110.             requests[i].join();
  111.     }
  112.     WSACleanup();
  113.     cout << "cn-lab2 var10 server stopped" << endl;
  114.     return 0;
  115. }
Advertisement
Add Comment
Please, Sign In to add comment