1

I need help, I'm trying to send this data in hexadeciamal, but always the packet_byte.size() and date() says: the express needs to have type of calsse, but has the type "char". I dont now what i need do, if anyone can help me.and if you can indicate what to study to understand this error Thank you.

#include <iostream>
#define ASIO_STANDALONE
#ifdef _WIN32
#define _WIN32_WINNT 0x0A00
#endif 
#include <asio.hpp>
#include <asio/ts/buffer.hpp>
#include <asio/ts/internet.hpp>





int main() {
    asio::error_code ec; //pega erros especificos

    //Cria o "context" 
    asio::io_context context;

    //Pega o endereço no qual estamos conectando1
    asio::ip::tcp::endpoint endpoint(asio::ip::make_address("ip", ec), 15559);
    
    //Cria o socket, o context ira entregar a implementaçao
    asio::ip::tcp::socket socket(context);

    //Diz ao socket para tentar se conectar
    socket.connect(endpoint, ec);

    if (!ec) {
        std::cout << "Conectado!" << std::endl; 
    }

    else {
        std::cout << "Falha de conecxao com o endereço: \n" << ec.message()/*pega mensagem associada ao erro */ << std::endl;
    }

    //Verifia se esta conectado
    if (socket.is_open()) { 

        const unsigned char packet_bytes [] = {
                "0x1e, 0x00, 0xe0, 0x55, 0xc0, 0x52, 0x09, 0x00,"
                "0x41, 0x00, 0x73, 0x00, 0x70, 0x00, 0x70, 0x00,"
                "0x69, 0x00, 0x65, 0x00, 0x72, 0x00, 0x72, 0x00,"
                "0x00, 0x00, 0x08, 0x9b, 0x95, 0x01"
         };
        


        //Se conexçao for True, escreve:
        //asio::buffer e um container, contendo bytes da string e sizer.
        socket.write_some(asio::buffer(packet_bytes.data(), packet_bytes.size()), ec);
        
        //Estava dando erro pelo tempo de resposta, programa indo mais rapido que a resposta.       
        socket.wait(socket.wait_read);
        
        size_t bytes = socket.available();
        std::cout << "Bytes Available: " << bytes << std::endl;

        if (bytes > 0) {
            //adiciona dados recebidos em um vector
            std::vector<char> vBuffer(bytes);
            socket.read_some(asio::buffer(vBuffer.data(), vBuffer.size()), ec);
            // 
            for (auto c : vBuffer) {
                std::cout << c;
            }
        }

        
    }
    system("pause");
    return 0;

}```
  • 1
    Is `unsigned char[]` a class? Does it have member functions `data()` and `size()`? Perhaps you could learn this from a textbook: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – VLL Aug 16 '22 at 10:09
  • 1
    Uhhm, `"0x1e, 0x00, 0xe0, 0x55, 0xc0, 0x52, 0x09, 0x00,"` is a string, not an array of bytes. And you probably wanted to use a `std::vector` instead of an array. Then `data()` and `size()` would make sense. It seems like you made some typos or are missing some fundamental knowledge about C++. In the latter case, we have a list of [good C++ books](https://stackoverflow.com/questions/388242/) – Lukas-T Aug 16 '22 at 10:12

2 Answers2

1

The accepted answer assumes you want to send the string. As the second commenter indicates - it is far more likely that you want to send the byte values represented by the text instead.

So:

// const std::vector<uint8_t> // or:
constexpr std::array<uint8_t, 30> packet_bytes{
    0x1e, 0x00, 0xe0, 0x55, 0xc0, 0x52, 0x09, 0x00, 0x41, 0x00,
    0x73, 0x00, 0x70, 0x00, 0x70, 0x00, 0x69, 0x00, 0x65, 0x00,
    0x72, 0x00, 0x72, 0x00, 0x00, 0x00, 0x08, 0x9b, 0x95, 0x01};

write(socket, asio::buffer(packet_bytes), ec);

If you don't need to hardcode the data/length itself, use e.g.

const std::vector<uint8_t> packet_bytes{
   // ... no further changes

The reading can also be greatly simplified. Here's my take:

std::vector<uint8_t> vBuffer(256); // some max capacity
auto n = socket.read_some(asio::buffer(vBuffer), ec);

vBuffer.resize(n);

If you, instead can just rely on EOF, you could use a dynamic buffer:

std::vector<uint8_t> vBuffer;
auto n = read(socket, asio::dynamic_buffer(vBuffer), ec);

Here's my take:

Live On Coliru

#include <boost/asio.hpp>
#include <iomanip>
#include <iostream>
namespace asio = boost::asio;
using asio::ip::tcp;

int main() {
    boost::system::error_code ec;
    asio::io_context context;
    
    tcp::socket socket(context);

    tcp::endpoint endpoint(asio::ip::make_address("ip", ec), 15559);
    if (!ec)
        socket.connect(endpoint, ec);

    if (!ec) {
        std::cout << "Connected!" << std::endl;
    } else {
        std::cout << "Failed to connect: \n" << ec.message() << std::endl;
        return 1;
    }

    // const std::vector<uint8_t> // or:
    constexpr std::array<uint8_t, 30> packet_bytes{
        0x1e, 0x00, 0xe0, 0x55, 0xc0, 0x52, 0x09, 0x00, 0x41, 0x00,
        0x73, 0x00, 0x70, 0x00, 0x70, 0x00, 0x69, 0x00, 0x65, 0x00,
        0x72, 0x00, 0x72, 0x00, 0x00, 0x00, 0x08, 0x9b, 0x95, 0x01};

    write(socket, asio::buffer(packet_bytes), ec);

    std::vector<uint8_t> vBuffer(256); // some max capacity
    auto n = socket.read_some(asio::buffer(vBuffer), ec);

    vBuffer.resize(n);

    std::cout << std::hex << std::setfill('0');
    for (uint8_t c : vBuffer)
        std::cout << " " << std::setw(2) << static_cast<int>(c);

    std::cout << "\n";
}

Of course, "ip" is not a valid IP address.

sehe
  • 374,641
  • 47
  • 450
  • 633
0

Your packet_bytes is a plain character array, it doesn't have data and size member function. Hence it is not possible to call packet_bytes.data() and packet_byte.size() on character array.

To create a asio::buffer from an array of characters, you need to pass the character array and its length to asio::buffer.

Please update your code as follows, then it should compile fine.

socket.write_some(asio::buffer(packet_bytes, sizeof(packet_bytes)), ec);
Aamir
  • 1,974
  • 1
  • 14
  • 18
  • Firstly this assumes that the string is to be sent (which seems unlikely). Secondly, don't use `sizeof` redundantly: https://www.boost.org/doc/libs/1_80_0/doc/html/boost_asio/reference/buffer/overload7.html It removes sources of error – sehe Aug 16 '22 at 12:22