Uczam się korzystać z COOST :: ASIO, wykonując przykłady w dokumentacji i rozszerzając się na nich. Przykłady Daytime.4 i Daytime.5 Pokaż jak Wdrożenie synchronicznej komunikacji klienta serwera UDP. Przykład wysyła dane, konstruując tablicę wagi typu Rodzaj, a następnie konstruując bufora wzmocnienia z tej tablicy:

boost::array<char, 1> send_buf  = {{ 0 }};
socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);

Jest też jeden przykład, w którym biorą Std :: String i przekazać je bezpośrednio do konstruktora buforów:

std::string message = make_daytime_string();
boost::system::error_code ignored_error;
socket.send_to(boost::asio::buffer(message),
remote_endpoint, 0, ignored_error);

Na razie w porządku. Próbowałem teraz wypełniając tablicę ciągów i wysyłając tę tablicę na mój serwer UDP. To zawsze powoduje, że serwer odbiera znaki śmieci przed rzeczywistą wiadomością. Kiedy buduję taki bufor w ten sposób:

std::string message = "I am still here";
boost::array<std::string, 1> send_buf2  = {{ message}};
socket.send_to(boost::asio::buffer(send_buf2), receiver_endpoint);

Dostaję taką wyjście: |��I am still here Kiedy moja tablica jest skonstruowana w ten sposób:

boost::array<std::string, 1> send_buf2  = {{ "I am still here" }};

Dostaję tylko znaki na śmieci w moim wyjściu. Długość odbioru w obu przypadkach będzie 32 (znaki).

Serwer czyta taki komunikat:

boost::array<char, 128> recv_buf;
size_t got = socket.receive_from(boost::asio::buffer(recv_buf),
                            remote_endpoint, 0, error);
std::string incoming(recv_buf.begin(), recv_buf.begin() + got);

Czy to tylko zły sposób konstruowania buforów wysychanych lub jest rozwiązanie tego problemu?

0
MYZ 17 październik 2020, 12:42

1 odpowiedź

Najlepsza odpowiedź

Nazywasz następującym przeciążeniem buffer Funkcja:

template<
    typename PodType,
    std::size_t N>
mutable_buffer buffer(
    boost::array< PodType, N > & data);

Który działa tylko z strąkiem. string nie jest typu POD.

Bufor w Boost ASIO można traktować jako parę: wskaźnik do danych i długości danych. W twoim przypadku tworzyłeś bufor, który wskazuje na binarną reprezentację ciągu, a nie do danych zarządzanych przez niego - Sekwencja znaków wskazywana przez wewnętrzny wskaźnik STD :: (ten wyjście {X0}} jest możliwe, gdy używana była optymalizacja smaczna). To wyjaśnia, dlaczego otrzymasz 32 bajtów, to tylko sizeof(std::string) dla wdrożenia biblioteki.

Jeśli chcesz wysłać dane zarządzane przez Boost :: tablicę ciągu, można użyć bufora kompozytowego:

const boost::array<std::string,2> a{{"I am still here", "xxx"}};
std::vector<boost::asio::const_buffers_1> v;
v.push_back(boost::asio::buffer(a[0]));
v.push_back(boost::asio::buffer(a[1]));

Utwórz wektor bufory i dodaj bufory utworzone na podstawie std::string jeden po drugim do tego wektora.

1
rafix07 17 październik 2020, 14:14