Получать структурированные данные из UDP-соединения

72
7

Я использую приложение Kolor для воспроизведения 3D-фильма. Это приложение отправляет статус игрока на порт UDP.

Сообщения UDP могут использоваться любым другим приложением. Например, трехмерный звуковой движок может использовать эту информацию для создания 3D-звука в соответствии с воспроизведением видео, сделанным Kolor Eyes.

Сообщения UDP находятся в формате JSON (http://www.json.org/). Поэтому вы должны использовать JSON-парсер для декодирования сообщения.

Вот текущая структура сообщения UDP:

"id": "ked" --- message identifier
"yaw": float --- yaw in radians
"pitch": float --- pitch in radians
"roll": float --- roll in radians
"url": string --- current video url
"state": enum --- playback state, integer possible values are : 0 (StoppedState), 1 (PlayingState), 2 (PausedState)
"position": int --- current video playback position in milliseconds

Я создаю приложение С# Для получения данных из UDP-порта и преобразования его в ASCII-строку

static void Main(string[] args)
{
int localPort = 7755;
IPEndPoint remoteSender = new IPEndPoint(IPAddress.Any, 0);
// Create UDP client
UdpClient client = new UdpClient(localPort);
UdpState state = new UdpState(client, remoteSender);
// Start async receiving
client.BeginReceive(new AsyncCallback(DataReceived), state);
// Wait for any key to terminate application
Console.ReadKey();
client.Close();
}
private static void DataReceived(IAsyncResult ar)
{
UdpClient c = (UdpClient)((UdpState)ar.AsyncState).c;
IPEndPoint wantedIpEndPoint = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = c.EndReceive(ar, ref receivedIpEndPoint);

// Check sender
bool isRightHost = (wantedIpEndPoint.Address.Equals(receivedIpEndPoint.Address)) || wantedIpEndPoint.Address.Equals(IPAddress.Any);
bool isRightPort = (wantedIpEndPoint.Port == receivedIpEndPoint.Port) || wantedIpEndPoint.Port == 0;
if (isRightHost && isRightPort)
{
string receivedText = Encoding.Default.GetString(receyiveBytes);
Console.WriteLine(receivedText);
}
// Restart listening for udp data packages
c.BeginReceive(new AsyncCallback(DataReceived), ar.AsyncState);

}

Но результат вывода в консоли показывает неправильный результат

  qbjs☺   E   ☼   ¬   >☻  ☻ id♥ ked   ↕♣  ♣ pitch         U← position  '    ♦ roll
♥ url ) file:///C:/Users/iman/Desktop/FIN_hi2.mp4 '¶ ♥ yaw ♀ ∟
0 @ T ' ~

спросил(а) 2015-07-10T20:55:00+03:00 5 лет, 4 месяца назад
1
Решение
117

Сообщения, отправленные KolorEyes, не кодируются как JSON, а некоторые двоичные производные. Это может быть Qt Binary Json (qbjs), но я не могу найти много информации об этом.

Qt5 внутренне преобразует документы JSON в двоичное представление, и это то, что передается через UDP. http://doc.qt.io/qt-5/qjsondocument.html

Это дает мне документ JSON в приложении Qt5:

void MainWindow::initSocket()
{
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 7755);

connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
}

void MainWindow::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;

udpSocket->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);

QJsonDocument document = QJsonDocument::fromBinaryData(datagram);
qDebug() << document;
}
}

ответил(а) 2015-07-13T13:14:00+03:00 5 лет, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема