Wpis z mikrobloga

#programowanie #qt #cpp

Mirki, orientujecie się może jak i czy się da w ogóle wysłać przez QTcpSocket wektor danych? Ogółem obiekt? W sensie daję mu wektor który ma 100 intów czy czegokolwiek i mu mówię, żeby mi go po prostu wysłał taki jaki jest a ktoś po stronie klienta spodziewa się tego wektora o takim rozmiarze? Czy muszę mu serializować to i odczytywać po prostu tego inta jednego za drugim i po drugiej stronie też łapać jednego inta na raz?
  • 19
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@Dymoslaw: Chwila chwila. Mam wektor. Nie QVector tylko std::vector. Taki mamy dziwaczny wymóg, że trzeba jakiejś klasy STLa użyć i tutaj nawet wypada to zrobić. W żadnym innym miejscu programu się w sumie nawet nie da. Program wyłapuje mi bufory dźwięku, które chcę przepisywać do wektora i potem wypluwać przez sieć.

Mogę to zrobić z palca i wysyłać to z buta - w pętli for robić socket->write potem socket->flush int
  • Odpowiedz
@Khaine
Lepiej serializować, ale jeżeli już musisz (jeżeli to np są sample i ważna jest latencja) to w QDataStream masz writeBytes i wrzucasz writeBytes( reinterpret_cast(wektor.data()), wektor.size() * sizeof( decltype(wektor)::value_type ) )
  • Odpowiedz
@lionbest: Tak, są to sample. Otrzymuję je od QAudioProbe w QAudioBuffer. Ten QAudioBuffer chcę przepisać do wektora, już najlepiej w osobnym wątku żeby nie tracić czasu (aczkolwiek paczka sampli przychodzi co 0,18 sekundy więc powinien zdążyć sam wewnątrz siebie to przepisać i wysłać gotowca). Gdy wątek skończy przepisywać ma dać znać kolejnemu wątkowi - serwerowi, że pod tym wskaźnikiem ma coś co ma wysłać. I jest to std::vector. Nie coś
  • Odpowiedz
@Khaine: Pamiętaj że TCP nie ma paczkowania, dlatego musisz sobie zapisać ile tych danych wysyłasz. O ile binarnie dane nie ma problemu aby wysłąć, to QDataStream przydaje się do opisania nagłówka i daje możliwość ich wysłania. Jest to dużo bezpieczniejsze od klecenia samemu własnego protokołu.
  • Odpowiedz
@Khaine: Lol, czy ja coś mówiłem o pliku? Mówiłem ze vectora możesz potraktorać jako ciągłą pamięć korzystając w C++11 z methody data, najlepiej kożystająć z QDataStream::writeBytes które tak naprawdę zapisuje quint32 z rozmiarem i dopiero robi QDataStream::writeRawData, dzięki temu nawet jak się byteorder na innej maszynie odwróci to sam protokół się nie r------e tylko poprawnie odczyta ten bufor, a co w nim będzie to sobie możesz też przesłać.
  • Odpowiedz
@Khaine:
1. Transmisja po TCP odbywa się porcjami, i druga strona musi cały przekaz sobie "poskładać" - dlatego aby to było możliwe podałem Ci wyżej prosty sposób: najpierw wysyłasz ilość przesyłanych danych, a dopiero potem same dane binarne.

2. W std::vector jest możliwy bezpośredni dostęp do poszczególnych elementów sekwencyjnie, nawet z wykorzystaniem arytmetyki wskaźników. link, dysponując więc wskaźnikiem na pierwszy element wektora (metoda data()) masz dostęp w zasadzie do
  • Odpowiedz
@Dymoslaw: Nadal nie mogę sobie tego poskładać. Po kolei.

QByteArray block; // tworzysz jakiś blok danych binarnych, ok

QDataStream sendStream(█, QIODevice::ReadWrite); // tworzysz data stream, który ma zapisywać do bloku w trybie
  • Odpowiedz
@Khaine: masz tu zobrazowane co i jak (to jest tylko fragment - pominąłem celowo sprawy związane z QTcpSocket:
1. void send(const std::vector* buffer) {

2. QByteArray block;
3. QDataStream sendStream(█, QIODevice::ReadWrite);
4. sendStream << quint16(0)
  • Odpowiedz
@Dymoslaw: Aaa, no wystarczyło powiedzieć, że to jest cofnięcie się na początek. Już kumam wszystko.

Tylko teraz pytanie - jak z odczytem tego? Chcę to wpisać do wektora potem mając byte array. No po prostu rekonstrukcja.
  • Odpowiedz
@Khaine:
Robisz rekonstrukcje w slocie podpiętym pod sygnał readyRead klasy QTcpSocket.
Wykorzystujesz QDataStream aby odczytać najpierw wartość przesłanych danych, a następnie te dane do QByteArray.
Na zakończenie odbudowujesz sobie std::vector z QByteArray
  • Odpowiedz
@lionbest: Akurat to QByteArray jest nawet wygodne, bo mogę na samym początku jakieś informacje jeszcze do tego wrzucić, np. ile jest kanałów, jakie próbkowanie itd.
  • Odpowiedz