client.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. /**
  15. * @brief Client::createMessageHandler
  16. * @param cb
  17. * @return
  18. */
  19. Client::MessageHandler Client::createMessageHandler(
  20. std::function<void()> cb) {
  21. return MessageHandler(cb);
  22. }
  23. /**
  24. * @brief Client::Client
  25. * @constructor
  26. * @param parent
  27. * @param count
  28. * @param arguments
  29. */
  30. Client::Client(QWidget *parent, int count, char** arguments) : QDialog(parent), argc(count), argv(arguments), m_client_socket_fd(-1) {}
  31. /**
  32. * @brief Client::~Client
  33. * @destructor
  34. */
  35. Client::~Client() {
  36. closeConnection();
  37. }
  38. /**
  39. * @brief Client::handleMessages
  40. */
  41. void Client::handleMessages() {
  42. char receive_buffer[2048];
  43. for (;;) {
  44. memset(receive_buffer, 0, 2048);
  45. int bytes_received = 0;
  46. bytes_received = recv(m_client_socket_fd, receive_buffer, 2048 - 2, 0);
  47. receive_buffer[2047] = 0;
  48. if (bytes_received == 0) {
  49. break;
  50. }
  51. emit Client::messageReceived(QString::fromUtf8(receive_buffer, 2048));
  52. }
  53. memset(receive_buffer, 0, 2048);
  54. ::close(m_client_socket_fd);
  55. }
  56. /**
  57. * @brief Client::start
  58. * @return A meaningless integer
  59. */
  60. void Client::start() {
  61. m_client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
  62. if (m_client_socket_fd != -1) {
  63. sockaddr_in server_socket;
  64. char* end;
  65. server_socket.sin_family = AF_INET;
  66. auto port_value = strtol(argv[2], &end, 10);
  67. if (port_value < 0 || end == argv[2]) {
  68. return;
  69. }
  70. int socket_option = 1;
  71. // Free up the port to begin listening again
  72. setsockopt(m_client_socket_fd, SOL_SOCKET, SO_REUSEADDR, &socket_option,
  73. sizeof(socket_option));
  74. server_socket.sin_port = htons(port_value);
  75. inet_pton(AF_INET, argv[1], &server_socket.sin_addr.s_addr);
  76. if (::connect(m_client_socket_fd, (sockaddr*)&server_socket,
  77. sizeof(server_socket)) != -1) {
  78. std::function<void()> message_send_fn = [this]() {
  79. this->handleMessages();
  80. };
  81. MessageHandler message_handler = createMessageHandler(message_send_fn);
  82. // Handle received messages on separate thread
  83. std::thread m_message_handling_thread(message_handler);
  84. m_message_handling_thread.detach();
  85. } else {
  86. qDebug() << errno;
  87. ::close(m_client_socket_fd);
  88. }
  89. }
  90. }
  91. /**
  92. * @brief Client::sendMessage
  93. * @param s[in] <const QString&> The message to send
  94. */
  95. void Client::sendMessage(const QString& s) {
  96. if (m_client_socket_fd != -1) {
  97. QByteArray byte_array = s.toLocal8Bit();
  98. ::send(m_client_socket_fd, byte_array.data(), byte_array.size(), 0);
  99. } else {
  100. qDebug() << "You must first open a connection";
  101. }
  102. }
  103. void Client::closeConnection() {
  104. if (m_client_socket_fd != -1) {
  105. ::close(m_client_socket_fd);
  106. }
  107. }