Advertisement
Vlad3955

TCPserver.cpp

Oct 28th, 2022
903
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.61 KB | None | 0 0
  1. #include "tcp_server.h"
  2.  
  3. #if !defined(MAX_PATH)
  4. #   define MAX_PATH (256)
  5. #endif
  6.  
  7.  
  8.  
  9. // TCPserver
  10. //==================================================================================
  11. //==================================================================================
  12.  
  13.  
  14. TCPserver::TCPserver(socket_wrapper::Socket&& client_sock) : client_sock_(std::move(client_sock)) {}
  15.  
  16. std::string TCPserver::get_request()
  17. {
  18.     std::array<char, MAX_PATH + 1> buffer;
  19.     size_t recv_bytes = 0;
  20.     const auto size = buffer.size() - 1;
  21.  
  22.     std::cout << "Reading user request..." << std::endl;
  23.     while (true)
  24.     {
  25.         auto result = recv(client_sock_, &buffer[recv_bytes], size - recv_bytes, 0);
  26.  
  27.         if (!result) break;
  28.  
  29.         if (-1 == result)
  30.         {
  31.             if (need_to_repeat()) continue;
  32.             throw std::logic_error("Socket reading error");
  33.         }
  34.  
  35.         auto fragment_begin = buffer.begin() + recv_bytes;
  36.         auto ret_iter = std::find_if(fragment_begin, fragment_begin + result,
  37.             [](char sym) { return '\n' == sym || '\r' == sym;  });
  38.         if (ret_iter != buffer.end())
  39.         {
  40.             *ret_iter = '\0';
  41.             recv_bytes += std::distance(fragment_begin, ret_iter);
  42.             break;
  43.         }
  44.         recv_bytes += result;
  45.         if (size == recv_bytes) break;
  46.     }
  47.  
  48.     buffer[recv_bytes] = '\0';
  49.  
  50.     auto result = std::string(buffer.begin(), buffer.begin() + recv_bytes);
  51.     std::cout << "Request = \"" << result << "\"" << std::endl;
  52.  
  53.     return result;
  54. }
  55.  
  56. bool TCPserver::send_buffer(const std::vector<char>& buffer)
  57. {
  58.     size_t transmit_bytes_count = 0;
  59.     const auto size = buffer.size();
  60.  
  61.     while (transmit_bytes_count != size)
  62.     {
  63.         auto result = send(client_sock_, &(buffer.data()[0]) + transmit_bytes_count, size - transmit_bytes_count, 0);
  64.         if (-1 == result)
  65.         {
  66.             if (need_to_repeat()) continue;
  67.             return false;
  68.         }
  69.  
  70.         transmit_bytes_count += result;
  71.     }
  72.  
  73.     return true;
  74. }
  75.  
  76. bool TCPserver::send_file(fs::path const& file_path)
  77. {
  78.     if (!(fs::exists(file_path) && fs::is_regular_file(file_path))) return false;
  79.  
  80.     std::vector<char> buffer(buffer_size);
  81.     std::ifstream file_stream(file_path, std::ifstream::binary);
  82.  
  83.     if (!file_stream) return false;
  84.  
  85.     std::cout << "Sending file " << file_path << "..." << std::endl;
  86.     while (file_stream)
  87.     {
  88.         file_stream.read(&buffer[0], buffer.size());
  89.         if (!send_buffer(buffer)) return false;
  90.     }
  91.  
  92.     return true;
  93. }
  94.  
  95. void TCPserver::server_run()
  96. {
  97.     const int len = 256;
  98.     char buffer[len] = {};
  99.     bool run = true;
  100.     int recv_len;
  101.  
  102.     while (run)
  103.     {
  104.         /*recv_len = recv(client_sock_, buffer, sizeof(buffer) - 1, 0);
  105.         buffer[recv_len] = '\0';
  106.         if (recv_len > 0)
  107.         {
  108.             std::cout << "Bytes received: \n" << recv_len << std::endl;
  109.             std::cout << buffer << std::endl;
  110.  
  111.             send(client_sock_, buffer, recv_len, 0);
  112.         }
  113.         std::cout << std::endl;*/
  114.         std::cout << "Client tid = " << std::this_thread::get_id() << std::endl;
  115.        
  116.         process();
  117.     }
  118. }
  119.  
  120. std::optional<fs::path> TCPserver::recv_file_path()
  121. {
  122.     auto request_data = get_request();
  123.     if (!request_data.size()) return std::nullopt;
  124.  
  125.     auto cur_path = fs::current_path().wstring();
  126.     auto file_path = fs::weakly_canonical(request_data).wstring();
  127.  
  128. #if defined(_WIN32)
  129.     std::transform(cur_path.begin(), cur_path.end(), cur_path.begin(),
  130.         [](wchar_t c) { return std::towlower(c); }
  131.     );
  132.     std::transform(file_path.begin(), file_path.end(), file_path.begin(),
  133.         [](wchar_t c) { return std::towlower(c); }
  134.     );
  135. #endif
  136.     if (file_path.find(cur_path) == 0)
  137.     {
  138.         file_path = file_path.substr(cur_path.length());
  139.     }
  140.  
  141.     return fs::weakly_canonical(cur_path + separ + file_path);
  142. }
  143.  
  144.  
  145.  
  146. bool TCPserver::process()
  147. {
  148.     auto file_to_send = recv_file_path();
  149.     bool result = false;
  150.  
  151.     if (std::nullopt != file_to_send)
  152.     {
  153.         std::cout << "Trying to send " << *file_to_send << "..." << std::endl;
  154.         if (send_file(*file_to_send))
  155.         {
  156.             std::cout << "File was sent." << std::endl;
  157.         }
  158.         else
  159.         {
  160.             std::cerr << "File sending error!" << std::endl;
  161.         }
  162.         result = true;
  163.     }
  164.  
  165.     return result;
  166. }
  167.  
  168. TCPserver::~TCPserver() {}
  169.  
  170.  
  171.  
  172.  
  173.  
  174. // Connector
  175. //==================================================================================
  176. //==================================================================================
  177.  
  178. Connecter::Connecter() {}
  179.  
  180. socket_wrapper::Socket Connecter::connect_to_client(unsigned short port)
  181. {
  182.     socket_wrapper::SocketWrapper sock_wrap_;
  183.  
  184.     sockaddr_storage clients_addr = { 0 };
  185.     socklen_t clients_addr_size;
  186.     const int flag = 1;
  187.  
  188.     addrinfo hints =
  189.     {
  190.         .ai_flags = AI_PASSIVE,
  191.         // Неважно, IPv4 или IPv6.
  192.         .ai_family = AF_INET,
  193.         // TCP stream-sockets.
  194.         .ai_socktype = SOCK_STREAM,
  195.         // Any protocol.
  196.         .ai_protocol = IPPROTO_TCP
  197.     };
  198.  
  199.     addrinfo* s_i = nullptr;
  200.     int status = 0;
  201.  
  202.     if ((status = getaddrinfo(NULL, std::to_string(port).c_str(), &hints, &s_i)) != 0)
  203.     {
  204.         std::string msg{ "getaddrinfo error: " };
  205.         msg += gai_strerror(status);
  206.         std::cout << msg;
  207.         //throw std::runtime_error(msg);
  208.         exit(EXIT_FAILURE);
  209.     }
  210.  
  211.     std::unique_ptr<addrinfo, decltype(&freeaddrinfo)> servinfo{ s_i, freeaddrinfo };
  212.  
  213.     while (true)
  214.     {
  215.         for (auto const* s = servinfo.get(); s != nullptr; s = s->ai_next)
  216.         {
  217.  
  218.             assert(s->ai_family == s->ai_addr->sa_family);
  219.             if (AF_INET == s->ai_family)
  220.             {
  221.                 char ip[INET_ADDRSTRLEN];
  222.  
  223.                 sockaddr_in* const sin = reinterpret_cast<sockaddr_in* const>(s->ai_addr);
  224.  
  225.                 sin->sin_family = AF_INET;
  226.                 sin->sin_port = htons(port);
  227.                 //sin->sin_addr.s_addr = INADDR_ANY;
  228.                 inet_pton(AF_INET, "192.168.100.9", &sin->sin_addr);
  229.  
  230.                 socket_wrapper::Socket s = { AF_INET, SOCK_STREAM, IPPROTO_TCP };
  231.  
  232.                 // Allow reuse of port.
  233.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&flag), sizeof(flag)) < 0)
  234.                 {
  235.                     std::cout << "Set SO_REUSEADDR error" << std::endl;
  236.                     exit(EXIT_FAILURE);
  237.                 }
  238.  
  239.                 if ((bind(s, reinterpret_cast<const sockaddr*>(sin), sizeof(sockaddr_in))) != 0)
  240.                 {
  241.                     std::cerr << sock_wrap_.get_last_error_string() << std::endl;
  242.                     std::cerr << "bind error" << std::endl;
  243.                     exit(EXIT_FAILURE);
  244.                 }
  245.  
  246.                 if ((listen(s, 10)) == -1)
  247.                 {
  248.                     std::cerr << "sever: listen\n";
  249.                     exit(EXIT_FAILURE);
  250.                 }
  251.  
  252.  
  253.                 std::cout << "Trying IP Address: " << inet_ntop(AF_INET, &sin->sin_addr.s_addr, ip, INET_ADDRSTRLEN) << std::endl;
  254.                 clients_addr_size = sizeof(clients_addr);
  255.  
  256.                 socket_wrapper::Socket newSock = accept(s, reinterpret_cast<sockaddr*>(&clients_addr), &clients_addr_size);
  257.                 if (!newSock)
  258.                 {
  259.                     std::cerr << sock_wrap_.get_last_error_string() << std::endl;
  260.                     std::cout << "accept error";
  261.                     exit(EXIT_FAILURE);
  262.                 }
  263.                 s.close();
  264.                 return newSock;
  265.             }
  266.             else if (AF_INET6 == s->ai_family)
  267.             {
  268.                 char ip6[INET6_ADDRSTRLEN];
  269.  
  270.                 sockaddr_in6* const sin = reinterpret_cast<sockaddr_in6* const>(s->ai_addr);
  271.  
  272.                 sin->sin6_family = AF_INET6;
  273.                 sin->sin6_port = htons(port);
  274.                 sin->sin6_addr = in6addr_any;
  275.                 //inet_pton(AF_INET6, "", &sin->sin6_addr);
  276.  
  277.                 socket_wrapper::Socket s = { AF_INET6, SOCK_STREAM, IPPROTO_TCP };
  278.  
  279.                 // Allow reuse of port.
  280.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&flag), sizeof(flag)) < 0)
  281.                 {
  282.                     std::cout << "Set SO_REUSEADDR error" << std::endl;
  283.                     exit(EXIT_FAILURE);
  284.                 }
  285.  
  286.                 if ((bind(s, reinterpret_cast<const sockaddr*>(sin), sizeof(sockaddr_in6))) != 0)
  287.                 {
  288.                     std::cerr << sock_wrap_.get_last_error_string() << std::endl;
  289.                     std::cerr << "bind error" << std::endl;
  290.                     exit(EXIT_FAILURE);
  291.                 }
  292.  
  293.                 if ((listen(s, 10)) == -1)
  294.                 {
  295.                     std::cerr << "sever: listen\n";
  296.                     exit(EXIT_FAILURE);
  297.                 }
  298.  
  299.                 std::cout << "Trying IPv6 Address: " << inet_ntop(AF_INET6, &sin->sin6_addr, ip6, INET6_ADDRSTRLEN) << std::endl;
  300.                 clients_addr_size = sizeof(clients_addr);
  301.  
  302.                 socket_wrapper::Socket newSock = accept(s, reinterpret_cast<sockaddr*>(&clients_addr), &clients_addr_size);
  303.                 if (!newSock)
  304.                 {
  305.                     std::cerr << sock_wrap_.get_last_error_string() << std::endl;
  306.                     std::cout << "accept error";
  307.                     exit(EXIT_FAILURE);
  308.                 }
  309.                 s.close();
  310.                 return newSock;
  311.             }
  312.         }  // for
  313.     }  // while
  314. }
  315.  
  316. Connecter::~Connecter() {}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement