Domanda

Nel un'altra domanda Un utente ha fornito un metodo per inviare dati a QuartzCompeser tramite UDP. Sembra che QuartzComposer sia molto particolare sull'imbottitura dei dati di byte inviati ad esso. In particolare richiede che ogni carattere inviato sia preceduto con " 0 0 0".

Sono stato in grado di deridere un rapido programma Python per risolvere questo problema:

from socket import *

PORT = 50000
N = 3.14159265358

# connect to Quartz Composer on localhost port 50000
s = socket(AF_INET, SOCK_DGRAM)
s.bind(('', 0))
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

for c in str(N):
    out = out + '\0\0\0' + c
s.sendto(out, ('225.0.0.0', PORT))

La sezione critica che ho bisogno di implementare in C ++ è il bit che assorbe un numero di punto galleggiante. Ecco un rapido Mock Up Python della sezione critica:

def padfloat(n):
    out = ''
    for c in str(n):
        out = out + '\0\0\0' + c
    return out

if __name__ == '__main__':
    print(padfloat(3.14159265358))

Certo, le mie costolette C ++ non sono così strette ma sono stato in grado di usare Boost per far funzionare UDP e inviare un singolo messaggio codificato "0.7":

//
// Working C++ to Quartz Network Test
// 

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::udp;

enum { max_length = 1024 };

int main(int argc, char* argv[])
{
  try
  {
boost::asio::io_service io_service;

udp::socket s(io_service, udp::endpoint(udp::v4(), 0));

udp::resolver resolver(io_service);
udp::resolver::query query(udp::v4(), "225.0.0.0", "50000");
udp::resolver::iterator iterator = resolver.resolve(query);

using namespace std; // For strlen.

// TODO: alter code to take in any number

for (;;) {
  std::cout << "Press Any Key to send 0.7: ";
  char request[max_length];
  std::cin.getline(request, max_length);
  // size_t request_length = strlen(request);
  char test [] = {0,0,0,'0',0,0,0,'.',0,0,0,'7','\0'};
  s.send_to(boost::asio::buffer(test, 12), *iterator);
  std::cout << "Sent\n";
}
  }
  catch (std::exception& e)
  {
std::cerr << "Exception: " << e.what() << "\n";
  }
  return 0;
}

Il problema piuttosto banale con cui ho bisogno di aiuto è come assumere un numero di punto galleggiante e formattarlo correttamente come un array di carbone da inviare con tutta l'imbottitura " 0 0 0" correttamente preparata. Sto per fare qualcosa di brutto, ma se qualcuno può indicarmi una soluzione elegante, sarei abbastanza felice di imparare un po '.

È stato utile?

Soluzione

Non ho a portata di mano un compilatore, ma questo dovrebbe essere sufficiente.

  1. Facciamo la conversione delle stringhe
  2. Crea un buffer 4 volte la dimensione (più 1 per la terminazione nulla), inizializzato su 0
  3. Copia nella stringa in ogni 4a posizione.

Non sono sicuro che ASIO si aspetti che il Terminator null faccia parte delle sue dimensioni, quindi ho seguito il tuo esempio.

float float_value = 4.2f;
std::string str = boost::lexical_cast<std::string>(float_value);

std::vector<char> char_buff((str.size() * 4) + 1, 0);

for (size_t i = 0; i < str.size(); i++)
  char_buff[(i * 4) + 3] = str[i];

s.send_to(boost::asio::buffer(&char_buff[0], char_buff.size()), *iterator);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top