client.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include <client.hpp>
  2. #include <arpa/inet.h>
  3. #include <netdb.h>
  4. #include <string.h>
  5. #include <sys/socket.h>
  6. #include <sys/types.h>
  7. #include <unistd.h>
  8. #include <functional>
  9. #include <cstring>
  10. #include <QDebug>
  11. #include <QByteArray>
  12. #include <string>
  13. #include <iostream>
  14. #include <vector>
  15. #include <future>
  16. #include <headers/kmessage_codec.hpp>
  17. #include <headers/json.hpp>
  18. using namespace KData;
  19. using json = nlohmann::json;
  20. flatbuffers::FlatBufferBuilder builder(1024);
  21. /**
  22. * @brief Client::createMessageHandler
  23. * @param cb
  24. * @return
  25. */
  26. Client::MessageHandler Client::createMessageHandler(
  27. std::function<void()> cb) {
  28. return MessageHandler(cb);
  29. }
  30. /**
  31. * @brief Client::Client
  32. * @constructor
  33. * @param parent
  34. * @param count
  35. * @param arguments
  36. */
  37. Client::Client(QWidget *parent, int count, char** arguments) : QDialog(parent), argc(count), argv(arguments), m_client_socket_fd(-1) {}
  38. /**
  39. * @brief Client::~Client
  40. * @destructor
  41. */
  42. Client::~Client() {
  43. closeConnection();
  44. }
  45. /**
  46. * @brief Client::handleMessages
  47. */
  48. void Client::handleMessages() {
  49. char receive_buffer[2048];
  50. for (;;) {
  51. memset(receive_buffer, 0, 2048);
  52. ssize_t bytes_received = 0;
  53. bytes_received = recv(m_client_socket_fd, receive_buffer, 2048 - 2, 0);
  54. receive_buffer[2047] = 0;
  55. if (bytes_received == 0) {
  56. break;
  57. }
  58. emit Client::messageReceived(QString::fromUtf8(receive_buffer, 2048));
  59. }
  60. memset(receive_buffer, 0, 2048);
  61. ::close(m_client_socket_fd);
  62. }
  63. /**
  64. * @brief Client::start
  65. * @return A meaningless integer
  66. */
  67. void Client::start() {
  68. m_client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
  69. if (m_client_socket_fd != -1) {
  70. sockaddr_in server_socket;
  71. char* end;
  72. server_socket.sin_family = AF_INET;
  73. auto port_value = strtol(argv[2], &end, 10);
  74. if (port_value < 0 || end == argv[2]) {
  75. return;
  76. }
  77. int socket_option = 1;
  78. // Free up the port to begin listening again
  79. setsockopt(m_client_socket_fd, SOL_SOCKET, SO_REUSEADDR, &socket_option,
  80. sizeof(socket_option));
  81. server_socket.sin_port = htons(port_value);
  82. inet_pton(AF_INET, argv[1], &server_socket.sin_addr.s_addr);
  83. if (::connect(m_client_socket_fd, reinterpret_cast<sockaddr*>(&server_socket),
  84. sizeof(server_socket)) != -1) {
  85. std::function<void()> message_send_fn = [this]() {
  86. this->handleMessages();
  87. };
  88. MessageHandler message_handler = createMessageHandler(message_send_fn);
  89. // Handle received messages on separate thread
  90. std::thread (message_handler).detach();
  91. } else {
  92. qDebug() << errno;
  93. ::close(m_client_socket_fd);
  94. }
  95. }
  96. }
  97. /**
  98. * @brief Client::sendMessage
  99. * @param s[in] <const QString&> The message to send
  100. */
  101. void Client::sendMessage(const QString& s) {
  102. if (m_client_socket_fd != -1) {
  103. // Convert QString to std byte vector
  104. // TODO: switch to using one or the other completely
  105. json data_json{};
  106. data_json["type"] = "custom";
  107. data_json["program"] = "placeholder";
  108. data_json["message"] = s.toUtf8().data();
  109. std::string json_string = data_json.dump();
  110. std::vector<uint8_t> fb_byte_vector{json_string.begin(), json_string.end()};
  111. // for (int i = 0; i < q_byte_array.size(); i++) {
  112. // fb_byte_vector.push_back(static_cast<uint8_t>(q_byte_array.at(i)));
  113. // }
  114. auto byte_vector = builder.CreateVector(fb_byte_vector);
  115. auto message = CreateMessage(builder, 69, byte_vector);
  116. builder.Finish(message);
  117. uint8_t* encoded_message_buffer = builder.GetBufferPointer();
  118. uint32_t size = builder.GetSize();
  119. qDebug() << "Size is " << size;
  120. uint8_t send_buffer[size + 4];
  121. send_buffer[0] = (size & 0xFF) >> 24;
  122. send_buffer[1] = (size & 0xFF) >> 16;
  123. send_buffer[2] = (size & 0xFF) >> 8;
  124. send_buffer[3] = (size & 0xFF);
  125. std::memcpy(send_buffer + 4, encoded_message_buffer, size);
  126. qDebug() << "Ready to send:";
  127. for (unsigned int i = 0; i < (size + 4); i++) {
  128. qDebug() << (char)*(send_buffer + i);
  129. }
  130. ::send(m_client_socket_fd, send_buffer, size + 4, 0);
  131. } else {
  132. qDebug() << "You must first open a connection";
  133. }
  134. }
  135. void Client::closeConnection() {
  136. if (m_client_socket_fd != -1) {
  137. ::close(m_client_socket_fd);
  138. m_client_socket_fd = -1;
  139. }
  140. }