Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // cn-lab5-client.cpp: определяет точку входа для консольного приложения.
- //
- #include "stdafx.h"
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #include <chrono>
- #include <condition_variable>
- #include <iostream>
- #include <map>
- #include <regex>
- #include <string>
- #include <thread>
- #include <winsock2.h>
- #pragma comment(lib, "ws2_32.lib")
- using namespace std;
- using namespace std::chrono;
- typedef unsigned long long ull;
- mutex m;
- condition_variable cvar;
- bool cvar_backup;
- class Network {
- private:
- SOCKET sock;
- sockaddr_in server_addr;
- public:
- Network() {
- WSAData wsadata;
- WSAStartup(0x0202, &wsadata);
- }
- ~Network() {
- WSACleanup();
- }
- void connect(const string &ip_addr, const int &port) {
- sock = socket(AF_INET, SOCK_STREAM, 0);
- sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.S_un.S_addr = inet_addr(ip_addr.c_str());
- server_addr.sin_port = htons(port);
- int ret = ::connect(sock, (sockaddr *)&server_addr, sizeof(server_addr));
- if (ret == INVALID_SOCKET) {
- throw exception("&wsa_error_connect");
- return;
- }
- }
- void disconnect() {
- closesocket(sock);
- }
- void send(const string &s) const {
- ::send(sock, s.c_str(), s.length(), 0);
- }
- string receive() const {
- char recv_buff[65536];
- int len = recv(sock, &recv_buff[0], sizeof(recv_buff) - 1, 0);
- if (len == -1)
- throw exception("&wsa_error_recv");
- recv_buff[len] = 0;
- return recv_buff;
- }
- }network;
- string tp_to_str(const system_clock::time_point &tp) {
- return to_string(time_point_cast<milliseconds>(tp).time_since_epoch().count());
- }
- class Commands {
- map<string, string> except_list = { {"&invalid_syntax", "Invalid syntax"} };
- private:
- map<string, void(Commands::*)(const smatch &) const> command_list;
- void sms(const smatch &input) const {
- auto tp = system_clock::now();
- regex pattern(R"(\-d|(\+?[0-9]+))");
- if (!regex_match(input.str(2), pattern))
- throw exception("&invalid_syntax");
- network.send(tp_to_str(tp) + " " + input.str(0));
- }
- void del(const smatch &input) const {
- auto tp = system_clock::now();
- regex pattern(R"(\+?[0-9]+)");
- if (!regex_match(input.str(2), pattern))
- throw exception("&invalid_syntax");
- network.send(tp_to_str(tp) + " " + input.str(0));
- }
- void exit(const smatch &input) const {
- network.send("&client_exit");
- cvar_backup = true;
- cvar.notify_one();
- }
- public:
- Commands() {
- command_list.emplace("exit", &Commands::exit);
- command_list.emplace("quit", &Commands::exit);
- command_list.emplace("sms", &Commands::sms);
- command_list.emplace("del", &Commands::del);
- }
- void exec(const smatch &input) const {
- try {
- (this->*command_list.at(input.str(1)))(input);
- }
- catch (exception e) {
- cout << except_list.at(e.what()) << endl;
- }
- }
- }commands;
- void user_input() {
- cout << "Enter your phone number: " << endl;
- string num;
- regex pattern(R"(\+?[0-9]+)");
- while (true) {
- getline(cin, num);
- if (regex_match(num, pattern))
- break;
- cout << "Invalid number" << endl;
- }
- network.send(num);
- while (true) {
- string s;
- getline(cin, s);
- if (s == "exit") {
- cvar_backup = true;
- cvar.notify_one();
- return;
- }
- regex pattern(R"(^(".+"|[.\S]+)\s*(".*"|[.\S]*)\s*(".*"|[.\S]*)\s*(".*"|[.\S]*)\s*$)");
- smatch match_results;
- regex_match(s, match_results, pattern);
- commands.exec(match_results);
- }
- }
- map<string, string> wsa_except_list = { { "&wsa_error_accept", "accept error " },
- { "&wsa_error_recv", "recv error " } };
- void port_listen() {
- map<string, string> ans_list = { { "&server_stop", "Server was stopped. Type \"exit\" to exit." },
- { "&sms_success", "Message sent successfully" },
- { "&del_success", "Message deleted successfully" },
- { "&del_fail_too_late", "Message was sent more than a minute ago" },
- { "&del_fail_not_deletable", "Message wasn't marked as deletable" },
- { "&del_fail_no_such_addressee", "You haven't sent any messages to this number yet" } };
- while (true) {
- string ans;
- try {
- ans = network.receive();
- }
- catch (exception e) {
- int wsa_error = WSAGetLastError();
- if (wsa_error != 0) {
- cout << wsa_except_list.at(e.what()) << wsa_error << endl;
- }
- return;
- }
- cout << ans_list.at(ans) << endl;
- }
- }
- int main()
- {
- try {
- network.connect("127.0.0.1", 5005);
- }
- catch (exception e) {
- cout << "Server is unreachable" << endl;
- return 1;
- }
- thread listen(port_listen);
- thread input(user_input);
- unique_lock<mutex> locked(m);
- cvar.wait(locked, [] {return cvar_backup; });
- network.disconnect();
- if (input.joinable())
- input.join();
- if (listen.joinable())
- listen.join();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment