Advertisement
Endil

cn-lab4-server

Nov 27th, 2015
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.33 KB | None | 0 0
  1. // cn-lab4-server.cpp: определяет точку входа для консольного приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <iostream>
  6. #include <thread>
  7. #include <string>
  8. #include <vector>
  9. #include <set>
  10. #include <windows.h>
  11.  
  12. #pragma comment(lib, "ws2_32.lib")
  13.  
  14. using namespace std;
  15.  
  16. vector<thread> client_list;
  17. set<SOCKET> open_socks;
  18.  
  19. int client_process(const SOCKET client_sock, const int client_id) {
  20.     SECURITY_DESCRIPTOR sd;
  21.     InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
  22.     SetSecurityDescriptorDacl(&sd, true, 0, false);
  23.     SECURITY_ATTRIBUTES sa;
  24.     sa.lpSecurityDescriptor = &sd;
  25.     sa.nLength = sizeof(sa);
  26.     sa.bInheritHandle = true;
  27.     HANDLE newstdin, newstdout, read_stdout, write_stdin;
  28.     CreatePipe(&newstdin, &write_stdin, &sa, 0);
  29.     CreatePipe(&read_stdout, &newstdout, &sa, 0);
  30.     STARTUPINFO si;
  31.     GetStartupInfo(&si);
  32.     si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  33.     si.wShowWindow = SW_HIDE;
  34.     si.hStdOutput = newstdout;
  35.     si.hStdError = newstdout;
  36.     si.hStdInput = newstdin;
  37.     PROCESS_INFORMATION pi;
  38.     auto cp = CreateProcess(L"C:\\Study\\CN\\cn-lab4-server-rp\\Debug\\cn-lab4-server-rp.exe", 0, 0, 0, true, CREATE_NEW_CONSOLE, 0, 0, &si, &pi);
  39.     if (cp == 0)
  40.         cout << GetLastError() << endl;
  41.     for (int request_id = 1;; request_id++) {
  42.         char recv_buff[8192];
  43.         auto len = recv(client_sock, &recv_buff[0], sizeof(recv_buff) - 1, 0);
  44.         if (len == -1) {
  45.             cout << "Client " << client_id << " was closed" << endl;
  46.             WriteFile(write_stdin, "&close", sizeof("&close"), 0, 0);
  47.             break;
  48.         }
  49.         recv_buff[len] = '\0';
  50.         //len++;
  51.         if (recv_buff == "&close") {
  52.             WriteFile(write_stdin, "&close", sizeof("&close"), 0, 0);
  53.             break;
  54.         }
  55.         cout << "Received request " << request_id << " from client #" << client_id << endl;
  56.         WriteFile(write_stdin, recv_buff, len, 0, 0);
  57.         string ans;
  58.         ReadFile(read_stdout, &ans, len, 0, 0);
  59.         send(client_sock, ans.c_str(), ans.length(), 0);
  60.         cout << "Sent answer for request " << request_id << " to client #" << client_id << endl;
  61.     }
  62.     CloseHandle(read_stdout);
  63.     CloseHandle(write_stdin);
  64.     CloseHandle(pi.hProcess);
  65.     closesocket(client_sock);
  66.     open_socks.erase(client_sock);
  67.     cout << "Client " << client_id << " disconnected" << endl;
  68.     return 0;
  69. }
  70.  
  71. int port_listen(const SOCKET &main_sock) {
  72.     for (int client_id = 1;; client_id++) {
  73.         sockaddr_in addr_client;
  74.         int client_addr_size = sizeof(addr_client);
  75.         SOCKET client_sock = accept(main_sock, (sockaddr *)&addr_client, &client_addr_size);
  76.         if (client_sock == INVALID_SOCKET) {
  77.             auto wsa_error = WSAGetLastError();
  78.             if (wsa_error != 10004)
  79.                 cout << "Accept error " << wsa_error << endl;
  80.             return 1;
  81.         }
  82.         cout << "Client " << client_id << " connected" << endl;
  83.         client_list.emplace_back(client_process, client_sock, client_id);
  84.         open_socks.insert(client_sock);
  85.     }
  86.     return 0;
  87. }
  88.  
  89. int main()
  90. {
  91.     cout << "cn-lab4 var10 server start" << endl;
  92.     WSAData wsadata;
  93.     WSAStartup(0x0202, &wsadata);
  94.     cout << "Windows Sockets API initialized" << endl;
  95.     SOCKET main_sock;
  96.     main_sock = socket(AF_INET, SOCK_STREAM, 0);
  97.     if (main_sock == INVALID_SOCKET) {
  98.         cout << "Main socket create error " << WSAGetLastError() << endl;
  99.         WSACleanup();
  100.         return 1;
  101.     }
  102.     cout << "Main socket created successfully" << endl;
  103.     sockaddr_in addr_local;
  104.     addr_local.sin_family = AF_INET;
  105.     addr_local.sin_addr.S_un.S_addr = 0;
  106.     addr_local.sin_port = htons(5004);
  107.     if (::bind(main_sock, (sockaddr *)&addr_local, sizeof(addr_local))) {
  108.         cout << "Bind error " << WSAGetLastError() << endl;
  109.         closesocket(main_sock);
  110.         WSACleanup();
  111.         return 2;
  112.     }
  113.     cout << "Port " << ntohs(addr_local.sin_port) << " bound successful" << endl;
  114.     if (listen(main_sock, 16))
  115.     {
  116.         cout << "Listen error " << WSAGetLastError() << endl;
  117.         closesocket(main_sock);
  118.         WSACleanup();
  119.         return  3;
  120.     }
  121.     cout << "Listening port 5004" << endl;
  122.     thread listen(port_listen, main_sock);
  123.     string s;
  124.     do {
  125.         cin >> s;
  126.     } while (s != "stop" && s != "exit");
  127.     closesocket(main_sock);
  128.     if (listen.joinable())
  129.         listen.join();
  130.     for (auto sock : open_socks) {
  131.         send(sock, "&stop", sizeof("&stop"), 0);
  132.         closesocket(sock);
  133.     }
  134.     for (unsigned int i = 0; i < client_list.size(); i++)
  135.         if (client_list.at(i).joinable())
  136.             client_list.at(i).join();
  137.     WSACleanup();
  138.     cout << "cn-lab4 var10 server stopped" << endl;
  139.     return 0;
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement