Отправка пакетов данных через сокет

ado

Новичок
Отправка пакетов данных через сокет

Есть задача отправлять неик пакеты данных на сервер.
Для этого создаю сединение через сокет и просто через send посылаю пакет.
Но возникает след проблема:
если в пакет создать таким образом:

PHP:
$data = "\xf1\x00\x40\x02\x32\x33\x34\x35\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x32\x33\x34\x35\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
то на сервер приходит бинарный пакет, т.е. php правильно интерпретирует \x в двойных кавычках как 16-ричное число.

Но если пакет создать таким образом:
PHP:
$_data1 = asc2hex("12345", 30);
$_data2 = asc2hex("12345", 30);
$data = "\xf1\x00\x40\x02" . $_data1 . $_data2;

function asc2hex ($str, $need_length = 0, $byte = '00') {
   		$data = '';
   		$adding_data = '';
   		$length = strlen($str);
   		$length = max($length, $need_length);
   		
   		for ($i=0; $i<$length; $i++) {
   			if(substr($str, $i, 1)) {
   				//$data .= sprintf("\x%02x", ord(substr($str, $i, 1)));//это тоже работает
   				//$data .= "\x".preg_replace('#(.*)#e', 'dechex(ord("$1"))', substr($str, $i, 1));//и это тоже работает
   				$data .= "\x".dechex(ord(substr($str, $i, 1)));// но это проще всего
   			} else {
   				$data .= "\x$byte";
   			}
   		}
   		
   		return $data;
	}

то данные в $_data1 и $_data2 интерпретируются как строковые, и пакет получается состоящим из заголовка в виде бинарных данных и идущей далее строки, соответственно сервер такой пакет бракует.

Как можно создать пакет, чтобы в него подставлялись заранее неизвестные данные($_data1 и $_data2, напримерый пришедшие постом) и интерпретировались php как 16-ричные данные, а не как строка.
 

Wicked

Новичок
$_data1 = "12345";
$_data2 = "12345";

или из поста:

$_data1 = $_POST["key1"];
$_data2 = $_POST["key2"];

естественно, твой протокол должен правильно работать с произвольными данными.

А функция asc2hex - вообще непонятно зачем она тебе.

-~{}~ 30.08.07 11:00:

а вообще, протокол у тебя странный... типа если в asc2hex передается строка меньше 30 символов, то она дополняется \x00-байтами. А если больше 30 символов, то вихается как есть. Не вижу в этом никакой логики.

-~{}~ 30.08.07 11:05:

а можно пример того, что тебе приходит постом, и как оно должно передаться серверу (заметь: не так, как ты думаешь оно должно быть обработано, чтобы оно было передану серверу правильно)?
 

Zetruger

ivan.chistyakov.name
16-ричных чисел не бывает, бывает 16-ричное представление чисел, а числа они одинаковые

преобразование ESCAPE последовательности \xf1 в бойт производит оператор " ... " (двойные кавыки)

исправить функ. asc2hex можно следующем способом
$data .= eval('return "\x' . dechex(ord(substr($str, $i, 1))) . '"');
 

gray07

Новичок
Сделать из "1234" шестнадцатиричное представление без eval тебе поможет функция [m]pack[/m].
 

gray07

Новичок
Насколько я понял, нужно отправлять данные в $_data1 и $_data2 не как строку, а как бинарное представление. Чтобы вместо "1234" было "\x04\xd2"
 

RushHourRider

Новичок
ado
Ты не понимаешь что делаешь.
Во-первых, что здесь "бинарнее"? =))) : var_dump("5" === "\x35");
Во-вторых escape-последовательности интерпретируются во время присвоения.
$a = "\x00" // в $a находится символ с кодом 0x00
$a = "\x"."00"; // в $a находится строка "\x00", потому что \x отдельно от 00 не является escape-последовательностью

asc2hex() - это шедевр монстроидального кода. Особенно вот это:
$data .= "\x".dechex(ord(substr($str, $i, 1)));// но это проще всего

Если тебе нужно передать _бинарные_ данные (то есть числа, например 123) как _строку_, то эти данные нужно преобразовать. Используй pack() - функция пакует числа в строки.

И неплохо бы знать о типах данных, какой размер имеет, скажем, unsigned integer и сколько байт это будет.
 
Сверху