Digitalisierte Elektroverteilung zur permanenten Verbraucherüberwachung
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IpTcpClient.cpp 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "IpTcpClient.h"
  2. #include <iostream>
  3. #include "DataModel.h"
  4. constexpr unsigned int bufferSize = 256;
  5. IpTcpClient::IpTcpClient(const std::string targetIP, const unsigned int targetPort) :
  6. ip(targetIP), port(targetPort), lastRequest(TCP_REQUESTS::NA)
  7. {
  8. }
  9. IpTcpClient::IpTcpClient(std::string targetIP, unsigned int targetPort, TCP_REQUESTS requestCode) :
  10. IpTcpClient(targetIP, targetPort)
  11. {
  12. requestCode = requestCode;
  13. }
  14. void IpTcpClient::connect()
  15. {
  16. asio::error_code error;
  17. tcp::resolver resolver(context);
  18. endpoints = resolver.resolve(ip, std::to_string(port));
  19. socket = std::make_unique<tcp::socket>(context);
  20. asio::connect(*socket, endpoints, error);
  21. if (error) {
  22. throw asio::system_error(error);
  23. }
  24. }
  25. void IpTcpClient::sendRequest(const TCP_REQUESTS& code)
  26. {
  27. this->lastRequest = code;
  28. inputStream.clear();
  29. asio::error_code error;
  30. std::string codeString = "cmd:" + std::to_string(toUnderlyingType(code)) + '\n';
  31. //Send the request code to server, which encodes the clients connection purpose
  32. size_t retVal = socket->write_some(asio::buffer(codeString), error);
  33. if (retVal == 0) {
  34. if (error == asio::error::eof) {
  35. //No error occured, sending finished
  36. std::cout << "Finnished sending request code" << std::endl;
  37. return;
  38. }
  39. throw asio::system_error(error);
  40. }
  41. }
  42. void IpTcpClient::processServerResponse() {
  43. if (TCP_REQUESTS::DOWNLOAD_DATA == lastRequest) {
  44. DataModel dataModel;
  45. inputStream >> dataModel;
  46. auto& savedData = dataModel.getSavedPublishedData();
  47. std::cout << "Summary: " << std::endl;
  48. for (auto& id : savedData) {
  49. std::cout << "\tID " << id.first << ": " << id.second.size() << " datapoints" << std::endl;
  50. }
  51. }
  52. else if (TCP_REQUESTS::GET_STATUS == lastRequest) {
  53. std::cout << inputStream.str();
  54. }
  55. }
  56. size_t IpTcpClient::waitRead()
  57. {
  58. size_t total_bytes_readed = 0, lastLen = 0;
  59. asio::error_code error;
  60. //std::array<char, bufferSize> buf;
  61. //Loop for the input pipe, init with 3 ('Invalid')
  62. std::array<int, 1> codeBuffer;
  63. codeBuffer[0] = 3;
  64. while(1){
  65. /*Get the serevrs intent
  66. CODE:
  67. 0: Invoke connection
  68. 1: Continuing
  69. 2: Finished
  70. 3: Invalid
  71. */
  72. std::array<char, 15> buf;
  73. socket->read_some(asio::buffer(buf));
  74. if (codeBuffer[0] != 1) //Steram does not continue
  75. break;
  76. //When stream continues
  77. while (codeBuffer[0] == 1) {
  78. size_t len = socket->read_some(asio::buffer(buf), error);
  79. total_bytes_readed += len;
  80. //Buffer as long as data readed
  81. if (len != 0) {
  82. std::cout << "Readed " << len << " bytes to buffer" << std::endl;
  83. if (len != bufferSize)
  84. lastLen = len;
  85. }
  86. // Connection closed cleanly by peer.
  87. if (error == asio::error::eof) {
  88. std::cout << "Transmition ended normally" << std::endl;
  89. break;
  90. }
  91. // Some other error.
  92. else if (error) {
  93. //Reply to server: 1 means failure
  94. std::array<char, 1>ans { 1 };
  95. socket->write_some(asio::buffer(ans));
  96. throw asio::system_error(error);
  97. }
  98. std::string data = std::move(std::string(buf.begin(), lastLen == 0 ? buf.end() : buf.begin() + lastLen));
  99. inputStream << data;
  100. }
  101. processServerResponse();
  102. //Reply to server: 0 means okay
  103. codeBuffer[0] = 0;
  104. socket->write_some(asio::buffer(codeBuffer));
  105. }
  106. return total_bytes_readed;
  107. }