Endil

cn-lab4-server

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