Нужен PHP аналог фунции Delphi "IdTCPClient1.WriteInteger(0);"
Есть серверное приложение, написанное на Дельфи с использованием компонент [Indy], для работы с tcp.
Необходимо разработать на php пару функций от данного программного комплекса.
Я коннекчусь (на php) к приложению с помощью сокетов. С отправкой/получением строковых данных нет проблем, а вот число не получается передать в том виде в котором оно есть на серверном приложении. Не могу понять как преобразовать число к необходимому формату.
Сама задача такова, при отправке текстовых данных на сервер нужно отправить их длину в виде 4х байт.
На вот как на дельфи клиентское приложение отправляет число:
я перепробовал разные способы, но что-то не то.
пробовал функции: pack, bin2hex, даже ord и chr
Помогите разобраться, может вообще не сокеты использовать?
$j = 4;
$str = '';
while($j--) {
$x = 0xFFFFFF00 ^ (0xFFFFFF00 | ($length >> 24));
$length = $length << 8;
$str .= chr($x);
}
// Теперь оно в $str...
//file_put_contents('file.txt', $str);
Это работает, если php работает на 32-битной системе. Если там 64 бит, то, наверно, придётся переделывать, так как тогда там integer будет храниться не в 4-х а в 8-ми байтах, я думаю.
Это работает, если php работает на 32-битной системе. Если там 64 бит, то, наверно, придётся переделывать, так как тогда там integer будет храниться не в 4-х а в 8-ми байтах, я думаю.
PHP Docs - Integers
$j = 4;
$str = '';
while($j--) {
$x = 0xFFFFFF00 ^ (0xFFFFFF00 | ($length >> 24));
$length = $length << 8;
$str .= chr($x);
}
// Теперь оно в $str...
//file_put_contents('file.txt', $str);
Это работает, если php работает на 32-битной системе. Если там 64 бит, то, наверно, придётся переделывать, так как тогда там integer будет храниться не в 4-х а в 8-ми байтах, я думаю.
Помог данный код!)
Теперь другая проблема, я данные с сервера получаю, нужен обратный алгоритм, не понимаю я с этими смещениями(( что там куда.
Ответ приходит в бинарном виде: [длина данных 8 байт][данные]
Ответ приходит в бинарном виде: [длина данных 8 байт][данные]
unpack тебе в руки. Только для начала нужно четко понимать, что конкретно за первые 8 байт и какова структуру последующих данных.
unpack нужно к целой строке применять или посимвольно?
Тут не может быть ни каких "посимвольно", ты же с потом байт работаешь! Максимум что есть это бинарная строка, но ни как не строка.
unpack применяется к тому куску данных которые у тебя в данное время есть и структуру которых ты знаешь. Для "[длина данных 8 байт][данные]" возможно пойдет такой вариант "c8header/*data", где с - signed (знаковых) байт, 8 - соответственно восемь того что слева от восьмерки, т.е. в итоге "8 знаковых байт", header - имя ключа в возвращаемом ассоциативном массиве, * - все остальные данные до конца, data - имя ключа в массиве. Привожу для примера ибо точное описание можно составить только точно зная формат бинарных данных.
На последок замечу, что PHP и бинарные данные вещи не очень согласующиеся, не под эти цели язык заточен. В том же erlang матчинг бинарных делается намного удобнее и более богат по возможностям.
unpack применяется к тому куску данных которые у тебя в данное время есть и структуру которых ты знаешь. Для "[длина данных 8 байт][данные]" возможно пойдет такой вариант "c8header/*data", где с - signed (знаковых) байт, 8 - соответственно восемь того что слева от восьмерки, т.е. в итоге "8 знаковых байт", header - имя ключа в возвращаемом ассоциативном массиве, * - все остальные данные до конца, data - имя ключа в массиве. Привожу для примера ибо точное описание можно составить только точно зная формат бинарных данных.
На последок замечу, что PHP и бинарные данные вещи не очень согласующиеся, не под эти цели язык заточен. В том же erlang матчинг бинарных делается намного удобнее и более богат по возможностям.
С этим все понятно, пасиб.
Еще вышло у меня недопонимание с нашим программистом, [длина данных 8 байт][данные], тут в 8 байтах зашита длинна (int64) в качестве контрольной суммы данных, а остальное как есть нужно записать в файл без изменений. Я же изначально понял, что [данные] это string и гонял бинарную строку туда-сюда...
Спасибо большое за помощь!
п.с.
со смещениями все равно ничего не понял...)
$x = 0xFFFFFF00 ^ (0xFFFFFF00 | ($length >> 24));
$length = $length << 8;
Просто php - такая штука, он всё-таки в первую очередь предназначен для обработки текстов. Можно даже удивиться, что в нём вообще есть такие операторы, как сдвиг битов вправо/влево и прочие побитовые операторы. За всё время, что я с ним работаю, мне эти операторы, собственно, ни разу и не требовались. Разве что только в учебно-экспериментальных целях, да вот тут, на форуме подсказать :-)))
Ну а чтобы пояснить, что делает этот цикл - придётся также пояснять, как хранится в памяти целочисленный int, а также, что есть текстовая строка. Это длинно, сейчас лень. Но если очень надо - можно попробовать конечно, как-нибудь.
Просто php - такая штука, он всё-таки в первую очередь предназначен для обработки текстов. Можно даже удивиться, что в нём вообще есть такие операторы, как сдвиг битов вправо/влево и прочие побитовые операторы. За всё время, что я с ним работаю, мне эти операторы, собственно, ни разу и не требовались. Разве что только в учебно-экспериментальных целях, да вот тут, на форуме подсказать :-)))
Ну а чтобы пояснить, что делает этот цикл - придётся также пояснять, как хранится в памяти целочисленный int, а также, что есть текстовая строка. Это длинно, сейчас лень. Но если очень надо - можно попробовать конечно, как-нибудь.
Я примерно понимаю, просто не сталкивался с этим... разъяснять не нужно, я доки почитаю.
Бинарной строкой обычно называют. Вопрос преобразования решается обычно через связку pack/unpack.