Endil

cn-lab5-client

Dec 17th, 2015
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.19 KB | None | 0 0
  1. // cn-lab5-client.cpp: определяет точку входа для консольного приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  6. #include <chrono>
  7. #include <condition_variable>
  8. #include <iostream>
  9. #include <map>
  10. #include <regex>
  11. #include <string>
  12. #include <thread>
  13. #include <winsock2.h>
  14.  
  15. #pragma comment(lib, "ws2_32.lib")
  16.  
  17. using namespace std;
  18. using namespace std::chrono;
  19.  
  20. typedef unsigned long long ull;
  21.  
  22. mutex m;
  23. condition_variable cvar;
  24. bool cvar_backup;
  25.  
  26. class Network {
  27. private:
  28.     SOCKET sock;
  29.     sockaddr_in server_addr;
  30. public:
  31.     Network() {
  32.         WSAData wsadata;
  33.         WSAStartup(0x0202, &wsadata);
  34.     }
  35.     ~Network() {
  36.         WSACleanup();
  37.     }
  38.     int connect(string ip_addr, int port) {
  39.         sock = socket(AF_INET, SOCK_STREAM, 0);
  40.         sockaddr_in server_addr;
  41.         server_addr.sin_family = AF_INET;
  42.         server_addr.sin_addr.S_un.S_addr = inet_addr(ip_addr.c_str());
  43.         server_addr.sin_port = htons(port);
  44.         int ret = ::connect(sock, (sockaddr *)&server_addr, sizeof(server_addr));
  45.         if (ret == INVALID_SOCKET) {
  46.             cout << "Server is unreachable" << endl;
  47.             cvar_backup = true;
  48.             cvar.notify_one();
  49.             return 1;
  50.         }
  51.         return 0;
  52.     }
  53.     int disconnect() {
  54.         closesocket(sock);
  55.         return 0;
  56.     }
  57.     int send(string s) {
  58.         ::send(sock, s.c_str(), s.length(), 0);
  59.         return 0;
  60.     }
  61.     string receive() {
  62.         char recv_buff[65536];
  63.         int len = recv(sock, &recv_buff[0], sizeof(recv_buff) - 1, 0);
  64.         if (len == -1)
  65.             return "";         
  66.         recv_buff[len] = 0;
  67.         return recv_buff;
  68.     }
  69. }network;
  70.  
  71. string tp_to_str(system_clock::time_point tp) {
  72.     return to_string(time_point_cast<milliseconds>(tp).time_since_epoch().count());
  73. }
  74.  
  75. class Commands {
  76. private:
  77.     map<string, int(Commands::*)(smatch)> command_list;
  78.     int sms(smatch input) {
  79.         auto tp = system_clock::now();
  80.         regex pattern(R"(\-d|(\+?[0-9]+))");
  81.         if (!regex_match(input.str(2), pattern)) {
  82.             cout << "Invalid syntax" << endl;
  83.             return 1;
  84.         }
  85.         network.send(tp_to_str(tp) + " " + input.str(0));
  86.         return 0;
  87.     }
  88.     int del(smatch input) {
  89.         auto tp = system_clock::now();
  90.         regex pattern(R"(\+?[0-9]+)");
  91.         if (!regex_match(input.str(2), pattern)) {
  92.             cout << "Invalid syntax" << endl;
  93.             return 1;
  94.         }
  95.         network.send(tp_to_str(tp) + " " + input.str(0));
  96.         return 0;
  97.     }
  98.     int exit(smatch input) {
  99.         network.send("&client_exit");
  100.         cvar_backup = true;
  101.         cvar.notify_one();
  102.         return 0;
  103.     }
  104. public:
  105.     Commands() {
  106.         command_list.emplace("exit", &Commands::exit);
  107.         command_list.emplace("quit", &Commands::exit);
  108.         command_list.emplace("sms", &Commands::sms);
  109.         command_list.emplace("del", &Commands::del);
  110.     }
  111.     int exec(smatch input) {               
  112.         try {
  113.             (this->*command_list.at(input.str(1)))(input);
  114.         }
  115.         catch (exception e) {
  116.             cout << e.what() << endl;
  117.         }
  118.         return 0;
  119.     }
  120. }commands;
  121.  
  122. int user_input() {
  123.     cout << "Entre your phone number: " << endl;
  124.     string num;
  125.     getline(cin, num);
  126.     network.send(num);
  127.     while (true) {
  128.         string s;
  129.         getline(cin, s);
  130.         regex pattern(R"(^(".+"|[.\S]+)\s*(".*"|[.\S]*)\s*(".*"|[.\S]*)\s*(".*"|[.\S]*)\s*$)");
  131.         smatch match_results;
  132.         regex_match(s, match_results, pattern);
  133.         commands.exec(match_results);
  134.     }
  135.     return 0;
  136. }
  137.  
  138. int port_listen() {
  139.     while (true) {
  140.         string ans = network.receive();
  141.         if (ans == "")
  142.             return 1;
  143.         if (ans == "&sms_success") {
  144.             cout << "Message sent successfully" << endl;
  145.             continue;
  146.         }
  147.         if (ans == "&del_success") {
  148.             cout << "Message deleted successfully" << endl;
  149.             continue;
  150.         }
  151.         if (ans == "&del_fail_too_late") {
  152.             cout << "Message was sent more than a minute ago" << endl;
  153.             continue;
  154.         }
  155.         if (ans == "&del_fail_not_deletable") {
  156.             cout << "Message wasn't marked as deletable" << endl;
  157.             continue;
  158.         }
  159.         if (ans == "&del_fail_no_such_addressee") {
  160.             cout << "You haven't sent any messages to this number yet" << endl;
  161.             continue;
  162.         }
  163.     }
  164.     return 0;
  165. }
  166.  
  167. int main()
  168. {
  169.     network.connect("127.0.0.1", 5005);
  170.     thread listen(port_listen);
  171.     thread input(user_input);
  172.     unique_lock<mutex> locked(m);
  173.     cvar.wait(locked, [] {return cvar_backup; });
  174.  
  175.     network.disconnect();
  176.     if (input.joinable())
  177.         input.join();
  178.     if (listen.joinable())
  179.         listen.join();
  180.     network.~network();
  181.     return 0;
  182. }
Add Comment
Please, Sign In to add comment