Question

Dans le une autre question un utilisateur a fourni une méthode pour envoyer données à QuartzComposer via UDP. Il semble que QuartzComposer est très particulier sur le rembourrage des octets de données qui lui sont envoyés. En particulier, il exige que chaque caractère envoyé soit précédé par « \ 0 \ 0 \ 0 ».

j'ai pu se moquer d'un programme Python rapide pour résoudre ce problème:

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 section critique que je dois mettre en œuvre en C ++ est le bit qui pads un nombre à virgule flottante. Voici un rapide Python maquette de la section critique:

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

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

Il est vrai, mon côtelettes C ++ ne sont pas si serré, mais j'ai pu utiliser boost pour obtenir UDP et en cours d'exécution et d'envoyer un seul message codé en dur « 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;
}

Le problème que je plutôt trivial ont besoin d'aide est de savoir comment prendre en un nombre à virgule flottante et formater correctement comme un tableau de caractères à envoyer avec tout le « \ 0 \ 0 \ 0 » padding correctement ajouté au début. Je suis sur le point de faire quelque chose de laid, mais si quelqu'un peut me pointer vers une solution élégante, je serais très heureux d'en apprendre un peu.

Était-ce utile?

La solution

Je n'ai pas un compilateur à portée de main, mais cela devrait être suffisant.

  1. Nous faisons la conversion de chaîne
  2. Créer un tampon à 4 fois la taille (plus 1 pour la terminaison nulle), initialisé à 0
  3. Copier dans la chaîne à chaque position 4.

Je ne sais pas si la terminaison asio attend nul pour faire partie de sa taille, donc je suivais votre exemple.

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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top