diff options
| author | crupest <crupest@outlook.com> | 2021-06-06 22:05:28 +0800 | 
|---|---|---|
| committer | crupest <crupest@outlook.com> | 2021-06-06 22:05:28 +0800 | 
| commit | f0309ee1e5cd268091f59f3aa377beca77d76c5c (patch) | |
| tree | 14b86eaf2b9181d9a171ee8c9d11173beeebec52 /works/life/computer-network-experiment | |
| parent | ff92a987ad05e40a1315306b31bbc4a219d2ee1d (diff) | |
| download | crupest-f0309ee1e5cd268091f59f3aa377beca77d76c5c.tar.gz crupest-f0309ee1e5cd268091f59f3aa377beca77d76c5c.tar.bz2 crupest-f0309ee1e5cd268091f59f3aa377beca77d76c5c.zip  | |
import(life): ...
Diffstat (limited to 'works/life/computer-network-experiment')
| -rw-r--r-- | works/life/computer-network-experiment/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | works/life/computer-network-experiment/Common.cpp | 48 | ||||
| -rw-r--r-- | works/life/computer-network-experiment/Common.h | 37 | ||||
| -rw-r--r-- | works/life/computer-network-experiment/Output.cpp | 4 | ||||
| -rw-r--r-- | works/life/computer-network-experiment/Output.h | 17 | ||||
| -rw-r--r-- | works/life/computer-network-experiment/server.cpp | 52 | 
6 files changed, 106 insertions, 54 deletions
diff --git a/works/life/computer-network-experiment/CMakeLists.txt b/works/life/computer-network-experiment/CMakeLists.txt index ecd8764..dc82736 100644 --- a/works/life/computer-network-experiment/CMakeLists.txt +++ b/works/life/computer-network-experiment/CMakeLists.txt @@ -9,7 +9,7 @@ set(CMAKE_CXX_STANDARD 17)  find_package(fmt CONFIG REQUIRED)
  find_package(Microsoft.GSL CONFIG REQUIRED)
 -add_library(base STATIC StringUtil.cpp Output.cpp)
 +add_library(base STATIC Common.cpp StringUtil.cpp Output.cpp)
  target_link_libraries(base PUBLIC Microsoft.GSL::GSL fmt::fmt)
  add_executable(client client.cpp)
 diff --git a/works/life/computer-network-experiment/Common.cpp b/works/life/computer-network-experiment/Common.cpp new file mode 100644 index 0000000..02ac550 --- /dev/null +++ b/works/life/computer-network-experiment/Common.cpp @@ -0,0 +1,48 @@ +#include "Common.h"
 +
 +#include "Output.h"
 +
 +#ifdef WIN32
 +#include <Windows.h>
 +#include <winsock.h>
 +#pragma comment(lib, "Ws2_32.lib")
 +#endif
 +
 +[[noreturn]] void PrintErrorMessageAndExit(StringView message,
 +                                           bool print_last_error) {
 +
 +  SendOutput(CRUT("{}\n"), message);
 +
 +  if (print_last_error) {
 +#ifdef WIN32
 +    auto error_code = WSAGetLastError();
 +    SendOutput(OutputType::Error, CRUT("Error code is {}.\n"), error_code);
 +    wchar_t buffer[500];
 +    if (!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
 +                            FORMAT_MESSAGE_ARGUMENT_ARRAY |
 +                            FORMAT_MESSAGE_IGNORE_INSERTS,
 +                        nullptr, error_code, 0, buffer, 500, nullptr)) {
 +      SendOutput(OutputType::Error, CRUT("Failed to format error message.\n"));
 +    } else {
 +      SendOutput(OutputType::Error, CRUT("{}\n"), buffer);
 +    }
 +#else
 +#endif
 +  }
 +
 +#ifdef WIN32
 +  WSACleanup();
 +#endif
 +
 +  std::exit(1);
 +}
 +
 +#ifdef WIN32
 +void InitWSA() {
 +  WSADATA wsa_data;
 +
 +  if (WSAStartup(MAKEWORD(2, 2), &wsa_data)) { // initialize wsa
 +    PrintErrorMessageAndExit(CRUT("Failed to initialize wsa."));
 +  }
 +}
 +#endif
 diff --git a/works/life/computer-network-experiment/Common.h b/works/life/computer-network-experiment/Common.h new file mode 100644 index 0000000..1f4fa23 --- /dev/null +++ b/works/life/computer-network-experiment/Common.h @@ -0,0 +1,37 @@ +#pragma once
 +#include "StringUtil.hpp"
 +
 +#include <iostream>
 +#include <string>
 +#include <string_view>
 +
 +#ifdef WIN32
 +using Char = wchar_t;
 +using String = std::wstring;
 +using StringView = std::wstring_view;
 +inline auto &input_stream = std::wcin;
 +inline auto &output_stream = std::wcout;
 +inline auto &error_stream = std::wcerr;
 +#define CRUT(string_literal) L##string_literal
 +
 +inline String ConvertCharString(std::string_view s) {
 +  return cru::ToUtf16WString(s);
 +}
 +#else
 +using Char = char;
 +using String = std::string;
 +using StringView = std::string_view;
 +inline auto &input_stream = std::cin;
 +inline auto &output_stream = std::cout;
 +inline auto &error_stream = std::cerr;
 +#define CRUT(string_literal) string_literal
 +
 +inline String ConvertCharString(std::string_view s) { return s; }
 +#endif
 +
 +[[noreturn]] void PrintErrorMessageAndExit(StringView message,
 +                                           bool print_last_error = true);
 +
 +#ifdef WIN32
 +void InitWSA();
 +#endif
 diff --git a/works/life/computer-network-experiment/Output.cpp b/works/life/computer-network-experiment/Output.cpp index 41e14e6..ac4a47b 100644 --- a/works/life/computer-network-experiment/Output.cpp +++ b/works/life/computer-network-experiment/Output.cpp @@ -8,10 +8,10 @@ void OutputThread() {      output_queue.blockingRead(output);
      switch (output.type) {
      case OutputType::Error:
 -      std::wcerr << output.message;
 +      error_stream << output.message;
        break;
      default:
 -      std::wcout << output.message;
 +      output_stream << output.message;
        break;
      }
    }
 diff --git a/works/life/computer-network-experiment/Output.h b/works/life/computer-network-experiment/Output.h index 0e53363..157e5c8 100644 --- a/works/life/computer-network-experiment/Output.h +++ b/works/life/computer-network-experiment/Output.h @@ -1,24 +1,25 @@  #pragma once
 +#include "Common.h"
  #include "StringUtil.hpp"
 -#include <iostream>
 -
  #include <fmt/format.h>
  #include <folly/MPMCPipeline.h>
  #include <folly/MPMCQueue.h>
 +#include <iostream>
 +
  enum class OutputType { Normal, Error };
  struct Output {
    Output() = default;
 -  Output(std::wstring message, OutputType type = OutputType::Normal)
 +  Output(String message, OutputType type = OutputType::Normal)
        : message(std::move(message)), type(type) {}
    CRU_DEFAULT_COPY(Output)
    CRU_DEFAULT_MOVE(Output)
    ~Output() = default;
 -  std::wstring message;
 +  String message;
    OutputType type;
  };
 @@ -28,17 +29,15 @@ inline void SendOutput(Output output) {    output_queue.blockingWrite(std::move(output));
  }
 -inline void SendOutput(std::wstring output) {
 -  SendOutput(std::move(output));
 -}
 +inline void SendOutput(String output) { SendOutput(std::move(output)); }
  template <typename... Args>
 -void SendOutput(std::wstring_view format, Args &&...args) {
 +void SendOutput(StringView format, Args &&...args) {
    output_queue.blockingWrite(fmt::format(format, std::forward<Args>(args)...));
  }
  template <typename... Args>
 -void SendOutput(OutputType type, std::wstring_view format, Args &&...args) {
 +void SendOutput(OutputType type, StringView format, Args &&...args) {
    output_queue.blockingWrite(
        Output{fmt::format(format, std::forward<Args>(args)...), type});
  }
 diff --git a/works/life/computer-network-experiment/server.cpp b/works/life/computer-network-experiment/server.cpp index 4942bb5..297114b 100644 --- a/works/life/computer-network-experiment/server.cpp +++ b/works/life/computer-network-experiment/server.cpp @@ -11,42 +11,12 @@  #include <string_view>
  #include <thread>
 -#include <Windows.h>
 -#include <winsock.h>
 -
 -#pragma comment(lib, "Ws2_32.lib")
 -
  const auto bind_address = "127.0.0.1"; // control bind address
  const u_short port = 1234;             // control bind port
 -
 -[[noreturn]] void
 -PrintErrorMessageAndExit(std::wstring_view message,
 -                         std::optional<int> error_code = std::nullopt) {
 -
 -  SendOutput(L"{}\n", message);
 -
 -  if (error_code) {
 -    SendOutput(OutputType::Error, L"Error code is {}.\n", *error_code);
 -    wchar_t buffer[500];
 -    if (!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
 -                            FORMAT_MESSAGE_ARGUMENT_ARRAY |
 -                            FORMAT_MESSAGE_IGNORE_INSERTS,
 -                        nullptr, *error_code, 0, buffer, 500, nullptr)) {
 -      SendOutput(OutputType::Error, L"Failed to format error message.\n");
 -    } else {
 -      SendOutput(OutputType::Error, L"{}\n", buffer);
 -    }
 -  }
 -
 -  WSACleanup();
 -
 -  std::exit(1);
 -}
 -
  void ResponseThreadProc(int socket, sockaddr_in address) {
    auto address_string = inet_ntoa(address.sin_addr);
 -  SendOutput(L"Connected to {}!\n", cru::ToUtf16WString(address_string));
 +  SendOutput(CRUT("Connected to {}!\n"), ConvertCharString(address_string));
    const std::string_view buffer = "Love you!!! By crupest!";
 @@ -72,23 +42,21 @@ void ResponseThreadProc(int socket, sockaddr_in address) {      byte_count_sent += byte_actually_sent;
    }
 -  SendOutput(L"Succeeded to send message to {} !\n",
 -             cru::ToUtf16WString(address_string));
 +  SendOutput(CRUT("Succeeded to send message to {} !\n"),
 +             ConvertCharString(address_string));
    closesocket(socket);
  }
  int main() {
 -  WSADATA wsa_data;
 -
 -  if (WSAStartup(MAKEWORD(2, 2), &wsa_data)) { // initialize wsa
 -    PrintErrorMessageAndExit(L"Failed to initialize wsa.", WSAGetLastError());
 -  }
 +#ifdef WIN32
 +  InitWSA();
 +#endif
    int server_socket;
    if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
 -    PrintErrorMessageAndExit(L"Failed to create socket.", WSAGetLastError());
 +    PrintErrorMessageAndExit(CRUT("Failed to create socket."));
    }
    sockaddr_in server_address;
 @@ -100,11 +68,11 @@ int main() {    if (bind(server_socket, reinterpret_cast<sockaddr *>(&server_address),
             sizeof(sockaddr_in)) == SOCKET_ERROR) {
 -    PrintErrorMessageAndExit(L"Failed to bind.", WSAGetLastError());
 +    PrintErrorMessageAndExit(CRUT("Failed to bind."));
    }
    if (listen(server_socket, SOMAXCONN) == SOCKET_ERROR) {
 -    PrintErrorMessageAndExit(L"Failed to listen.", WSAGetLastError());
 +    PrintErrorMessageAndExit(CRUT("Failed to listen."));
    }
    while (true) {
 @@ -116,7 +84,7 @@ int main() {                 &sin_size);
      if (client_socket == INVALID_SOCKET) {
 -      PrintErrorMessageAndExit(L"Failed to accecpt", WSAGetLastError());
 +      PrintErrorMessageAndExit(CRUT("Failed to accecpt"));
      }
      std::thread response_thread(ResponseThreadProc, client_socket,
  | 
