2013-10-25 2 views
2

Я получаю данные по UDP в PHP. После прохождения буфера через функцию BIN2HEX в PHP я в конечном итоге с чем-то, напоминающим Raw Data, как показано ниже в примереПеревести UDP-пакет данных в удобочитаемую форму в PHP

Вот мой PHP код:

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
socket_bind($socket, "0.0.0.0" , 20500); 

$from = ''; 
$port = 0; 
socket_recvfrom($socket, $buf, 512, 0, $from, $port); 

$file = 'testudp.txt'; 
// Open the file to get existing content 
$current = file_get_contents($file); 
// Append a new log line(s) to file 
$current .= "New Connection " . date('Y-m-d H:i:s') . " \n" . bin2hex($buf) . "\n"; 
// Write the contents back to the file 
file_put_contents($file, $current); 
echo "Received connection from remote address $from and remote port $port" . PHP_EOL; 

Какие результаты в чем-то вроде 83 05 01 02 03 04 05 01 01 01 02 00 01 4F B4 64 88 4F B4 64 88 13 BF 71 A8 BA 18 A5 06 00 00 1333 00 00 00 00 11 11 02 ... , но без пространства.

Пример данных и что он ought, чтобы перевести на: обратите внимание, что перевод начинается только после первых 9 байтов, затем по адресу 2, а затем снова пропускает 2.

Raw Data: 
83 05 01 02 03 04 05 01 01 01 02 00 01 4F B4 64 88 4F B4 64 
88 13 BF 71 A8 BA 18 A5 06 00 00 1333 00 00 00 00 11 11 02 
33 44 44 55 55 66 77 88 99 10 11 ?? 00 ?? 

Decoded: 
    -------Message Header-------- 
    01   Service Type, for this message 1 = Acknowledged Request 
    02   Message Type, for this message 2 = Event Report 
    -------Event Report---------- 
    4FB46488  Update Time (5/17/12 @ 2:38pm) 
    4FB46488  Time of Fix (5/17/12 @ 2:38pm) 
    13BF71A8  Latitude (33.1313576) 
    BA18A506  Longitude (-117.2790010) 
    00001333  Altitude 
    00000000  Speed 
    1111   Heading 
    02   Satellites 
    33   Fix Status 
    4444   Carrier 
    5555   RSSI 
    66   Comm State 
    77   HDOP 
    88   Inputs 
    99   Unit Status 
    10   Event Index 
    11   Event Code 
    ??   Accums (# of 4-byte Accum List values) 
    00   Spare 
    ??   Accum List (Varies depending on the # of Accums reporting) 

Я попробовал различные декодеры шестнадцатеричной к ASCii, я также пытался распаковку() в PHP все безрезультатно.
Как вы переводите данные в нечто похожее на пример с помощью PHP? i.e. Как бы BA18A506 в конечном итоге дать мне данные (неформатированные или нет), чтобы соответствовать Longitude (-117.2790010) в удобной для читаемости форме?

EDIT: Документов указать Note that all bytes in multi-byte fields are transmitted in Net Endian format (Big Endian) where the most significant bits are transmitted first. For example, for a 32-bit field, bits 31-24 are transmitted first, 16-23 second, 8-15 third and 0-7 last , если это помогает на всех.

+1

Я думаю, вам нужно прочитать документацию/руководство источника, предоставляющего вам эти данные. Я имею в виду, как '13BF71A8' перевести на' Latitude (33.1313576) ', если он не следует определенному« стандарту »или« шаблону », который настроен у поставщика? Меньший пример, я мог бы дать вам '10', вы, возможно, подумаете о числе * десять *, но я на самом деле имел в виду * два *, так как он двоичный с моей точки зрения. – HamZa

+1

@HamZa Большое спасибо, что посмотрели. Я прочитал довольно скудную документацию, и они не упоминают ничего конкретного, поэтому я надеялся, что кто-то здесь может иметь ключ. Ценить это. Если это не актуально, я удалю вопрос. –

+0

Вы разрешили декодирование пакета? Не могли бы вы поделиться тем, что у вас получилось? – waney

ответ

2

unpack() или unpack() для каждого двоичного файла substr() должны в конце получить вас там, где вы хотите. Но, как говорится Хамза, вы должны знать, какой формат это ...

$test = "\x06\xA5\x18\xBA"; 
var_dump(unpack('l',$test)); 

результат:

-1172790010 

Просто добавьте. на правильном месте

Пример кода распаковывать первую часть (продлить/правильно, где это необходимо)

Изменить код, чтобы получать в буфер вместо файла: socket_recv ($ розеткой, $ BUF, 512, 0);

Затем вы можете использовать буфер $ БУФ (на данный момент я ввести данные выборки, которую вы предоставили)

// Now we use some test data 
$buf = "\x83\x05\x01\x02\x03\x04\x05\x01\x01\x01\x02\x00\x01\x4F\xB4\x64\x88\x4F\xB4\x64\x88\x13\xBF\x71\xA8\xBA\x18\xA5\x06\x00\x00\x13\x33\x00\x00\x00\x00\x11\x11\x02\x33\x44\x44\x55\x55\x66\x77\x88\x99\x10\x11"; 

// field definition 
$fields = array(); 
$fields['header'] = array(9, 'c*'); 
$fields['serviceType'] = array(1, 'c'); 
$fields['messageType'] = array(1, 'c'); 
$fields['skip'] = array(2, 'c'); 
$fields['updateTime'] = array(4, 'l'); 
$fields['fixTime'] = array(4, 'l'); 
$fields['longitude'] = array(4, 'l'); 
$fields['latitude'] = array(4, 'l'); 
$fields['altitude'] = array(4, 'l'); 
$fields['speed'] = array(4, 'l'); 
// etc. 

$values = array(); 
$start = 0; 
foreach($fields as $type=>$setting) { 
    list($len, $format) = $setting; 
    $values[$type] = unpack($format, strrev(substr($buf, $start, $len))); 
    $start += $len; 
} 

var_dump($values); 

Выведет что-то вроде:

["serviceType"]=> 
array(1) { 
    [1]=> 
    int(1) 
} 
["messageType"]=> 
array(1) { 
    [1]=> 
    int(2) 
} 
["skip"]=> 
array(1) { 
    [1]=> 
    int(1) 
} 
["updateTime"]=> 
array(1) { 
    [1]=> 
    int(1337222280) 
} 
["fixTime"]=> 
array(1) { 
    [1]=> 
    int(1337222280) 
} 
["longitude"]=> 
array(1) { 
    [1]=> 
    int(331313576) 
} 
["latitude"]=> 
array(1) { 
    [1]=> 
    int(-1172790010) 
} 
["altitude"]=> 
array(1) { 
    [1]=> 
    int(4915) 
} 
["speed"]=> 
array(1) { 
    [1]=> 
    int(0) 
} 

разделите широту и долготу 10000000 (10M), чтобы получить реальную долготу и широту

+0

Приношу свои извинения, я должен был поставить это в вопросе. В ответ на ваш вопрос 'Обратите внимание, что все байты в многобайтовых полях передаются в формате Net Endian (Big Endian), где сначала передаются наиболее важные биты. Например, для 32-битового поля сначала передаются биты 31-24, 16-23 секунды, 8-15 третьих и 0-7 последние' - это единственное, что я могу получить из документов. –

+0

Хорошо, это облегчает его. –

+0

Вау - спасибо Рональду. Извиняюсь за то, что он краток в вопросе! Можете ли вы просто указать, что делает '\ x'? Также знаете ли вы, есть ли в PHP скрипт/скрипт, который может обрабатывать работу по расшифровке таких пакетов, теперь мы знаем, в каком формате он находится? –

Смежные вопросы