Проблема:
Я пишу программу на C ++, где хочу прочитать поток данных из сокета TCP / IP.Данные состоят из нескольких пакетов различной длины и типов данных, однако все они принимаются в шестнадцатеричном формате.Длины пакетов и их типы данных можно увидеть на этом изображении: .Я хочу преобразовать полученные данные в шестнадцатеричном формате обратно в соответствующие исходные типы данных пакетов.
Фон и то, что я пробовал:
Я нашел довольно простой способ сделать это вPython:
- получать каждый пакет в соответствии с их известной длиной
- кодировать их как шестнадцатеричные
- распаковывать их в соответствии с их типом данных
Вот пример:
import socket
import struct
HOST = "192.168.0.25" # The remote host
PORT_30003 = 30003
while (True):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT_30003))
print ""
packet_1 = s.recv(4)
packet_2 = s.recv(8)
packet_3 = s.recv(48)
packet_4 = s.recv(48)
packet_5 = s.recv(48)
packet_6 = s.recv(48)
packet_7 = s.recv(48)
packet_8 = s.recv(48)
packet_9 = s.recv(48)
packet_10 = s.recv(48)
packet_11 = s.recv(48)
packet_1 = packet_1.encode("hex")
messageSize = struct.unpack('!i', packet_1.decode('hex'))[0]
print "messageSize = ", messageSize
packet_2 = packet_2.encode("hex")
Time = struct.unpack('!d', packet_2.decode('hex'))[0]
print "Time = ", Time
Меня не волнуют следующие пакеты, поэтому я перейду к соответствующим (начиная с packet_12 и далее).Я собираюсь разбить каждый 48-байтовый пакет на более мелкие 8-байтовые пакеты, так как 48 байтов - это на самом деле 6 отдельных значений, как показано на рисунке выше ...
packet_12x = s.recv(8)
packet_12x = packet_12x.encode("hex")
x = struct.unpack('!d', packet_12x.decode('hex'))[0]
print "X = ", x * 1000
packet_12y = s.recv(8)
packet_12y = packet_12y.encode("hex")
y = struct.unpack('!d', packet_12y.decode('hex'))[0]
print "Y = ", y * 1000
# And so on.....
Это приводит к длине сообщения (который всегда должен быть 1108), время сервера и положение X, Y инструмента робота.
Попытка C ++:
При попытке сделать это в C ++ я немного путаюсь с типами данных, порядком байтов и т. Д. Мне удалось правильно сформировать первый пакет.(печать 1108 как я и ожидал).Однако следующий пакет не совпадает с выводом из реализации Python.Вот что у меня есть:
connectTcpClient("192.168.0.25");
// This works as expected
int buffer1;
recv(sock, &buffer1, 4, 0);
buffer1 = ntohl(buffer1);
// Prints "messageSize = 1108"
std::cout << "messageSize = " << buffer1 << std::endl;
// This does not produce the same result as the Python code
// When trying with a unsigned long long int instead of double
double buffer2;
recv(sock, &buffer2, 8, 0);
buffer2 = ntohl(buffer2);
// This prints "Time: 0"
std::cout << "Time: " << buffer2 << std::endl;
Если я вместо этого попытаюсь объявить свой buffer2
как таковой: unsigned long long int buffer2
Я получу что-то ближе к тому, что я хочу, однако это, конечно, не двойникЯ жду.А приведение buffer2
к double
просто приводит к 0.
Ожидаемый результат
Я ожидаю, что время будет примерно 1379408.432, а не целым числом.Координаты X, Y и Z из пакета_12 также должны быть двойными.