Страницы

Поиск по вопросам

четверг, 6 июня 2019 г.

Замена данных в TCP пакете

В общем, есть два устройства. Одно отсылает пакеты, а другое, соответственно, их принимает, изменяет и дальше отправляет в сеть.
И тут еще суть в том, что нужно оставить заголовки пакета, окончание, а содержимое заменить на другое.
То есть что получается: мне нужно поднять сервер, получить пакет, убрать из него содержимое и вставить своё. Отправить пакет дальше. Даже схемка есть:
Вот - N - это количество "D".

Не понимаю, с чего начинать, т.к. с этим сталкиваюсь в первый раз. И хотелось бы понять, что нарисовано на картинке.


Ответ

Тут вроде ничего сложного. На картинке показана структура 2-х пакетов: Сообщение, которое к вам приходит. Сообщение, которое вы должны отослать. По каждому сообщению подробно расписана структура следования байтов (Б1, Б2 и т.д.), также показано, какую часть и куда нужно переносить. Тело исходного сообщения состоит из массива данных структуры "D", каждый элемент по 6 байт. Но я сейчас какие-то прописные истины перечислил)), которые вы и сами, наверное, поняли) Но вот что мне не понятно по этому рисунку: Во-первых, "Измерительное сообщение 98 байт максимум" - следовательно, пакет нефиксированной длины, а как мы узнаем об окончании пакета? + не хватает 10 байт в описании, максимум 98, а на картинке расписано только 88 байт. Может, еще есть какая-нибудь информация? Во-вторых, тело исходного сообщения на картинке 84 байта, а уместить его нужно в 103 байта, с ним производятся какие-то манипуляции? Или нужно добивать нулями до определенной длинны? =============================================== Все еще остаются вопросы) вот смотрите примерный алгоритм На вашем сервере(на рис - прибор 2), считываем поток байт, для начала берем первый байт и сверяем заголовок, судя по рисунку заголовок всегда 23 если да то продолжаем читать, если нет то нужно больше информации о других пакетах и дальнейших действиях Теперь когда мы поняли что за пакет, нам нужно узнать остальные данные, для этого нужно понять длинну пакета, и тут опять непонятно как ее вычислить она всегда фиксирована и равна = 113 байт ( тогда вам нужно считать еще 110 байт + crc(2 байта) ), или "N" - это количество D, как говорил @avp, тогда вам нужно считать еще один байт, будем считать что это count, тогда формула будет такая count * 6 + crc( 2 байта ) Когда вы получили тело сообщения, нужно сверить crc ( последние 2 байта), но тут не написано для какой части сообщения его сверять? Если crc совпал то теперь можно формировать новый пакет, но как его формировать тоже не совсем понятно

Получение изображения курсора над Flash

Веб-приложение на делфи, в качестве браузера использую компонент Tchromium. В него загружаю сайт, в котором имеется игра на flash, с помощью кода: var CI: TCursorInfo; begin CI.cbSize := SizeOf(CI); GetCursorInfo(CI); Image1.Picture.Icon.Handle := CI.hCursor; В image1 получаю изображения курсора. Но если курсор над Flash, и он там заменяется своим курсором, то в image1 ничего не отображается. CI.hCursor равен 351474505, и этому значению равен любой нарисованный курсор из flash. Как можно получить точное изображение текущего курсора над flash или вообще отследить это изменение?


Ответ

Вопрос в следующем - так ли необходимо писать собственную реализацию или можно использовать SCAR Divi? Он как раз позволяет написать свой скрипт. Хукает элементы интерфейса, флэш тоже (например, на нем пишут автокликеры для игр и прочее). Обновление @Sergei123 http://www.scar-divi.com/ - лично мне данное творение очень понравилось. Автор с пониманием дела относится к данному проекту. @Sergei123 порадовало, что есть возможность отслеживать появление в flash-игре какой-нибудь картинки и в соответствии с этим предпринимать какие-либо действия (произвести клик по координатам места появления картинки в отслеживаемой области). И еще. Скрипт - это я погорячился. Программа позволяет создать свое приложение с графическим интерфейсом (я же просто отслеживал все происходящее в бесконечном цикле и производил действия по условию).

Как отобразить русский текст?

Перехватываю пакет, и там иногда бывает текст на английском, а иногда - на русском. С английским проблем нету, отображается хорошо, а вот что с русским делать?
Как узнать русский или английский текст и как потом отобразить русский?


Ответ

Необходимо знать кодировку текста, например, она может быть указана в Content-Type http-заголовке и/или в xml-декларации и/или как внутри html-документа и т.д. Если данные из файла, то некоторые кодировки (utf-8, utf-16, utf-32) позволяют указывать BOM (специальная метка в начале файла). В худшем случае, существуют библиотеки такие как chardet, которые пытаются угадать кодировку по содержимому (это не всегда можно точно сделать).
Нельзя содержимое называть текстом, если не известна его кодировка. Абсолютный Минимум, который Каждый Разработчик Программного Обеспечения Обязательно Должен Знать о Unicode и Наборах Символов
Обновление
Если кодировка текста известна, то шаг номер два: превратить байты в Юникодный текст. Для некоторых кодировок можно использовать MultiByteToWideChar(). Шаг номер три: отобразить Юникод. Для печати в консоль, можно использовать WriteConsoleW() или _setmode(_fileno(stdout), _O_U16TEXT); wprintf(L"%s
", unicode_text); (printf, cout, wcout не должны использоваться в последнем варианте). Чтобы буквы были видны в консоли, нужно создать ярлык для приложения и настроить в нём шрифт (например, Lucida console) и запускать программу через ярлык. При печати в файл (и type) можно BOM добавить.
Вот полный пример кода из msdn как напечатать Юникод текст в Виндовую консоль с cmd.exe
#include #include #include
int main(void) { _setmode(_fileno(stdout), _O_U16TEXT); wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd
"); return 0; }
Повторюсь: это решение не совместимо с printf(). Не нужно вызывать SetConsoleCP или SetConsoleOutputCP c вышеприведённым кодом. Единственное что нужно, чтобы (TrueType) шрифт был настроен в консоле (такой как Lucida Console).

Android orientation & DialogFragment

Добрый день! Проблема: при открытом DialogFragment при смене ориентации вылетает исключение. Сталкивался ли кто-нибудь с подобным и есть ли методы решения? Также интересует: как отследить изменения в EditText не через TextWatcher? (Требуется отловить лишь события набора текста, без события программного изменения.) С уважением, Игорь.


Ответ

По поводу того, что вылетает exception при смене ориентации. Какое именно исключение? Покажите stacktrace. Попробуйте сделать следующее: добавьте setRetainInstance(true) в методе onCreateDialog() Насчет того как отловить изменения в EditText, есть несколько способов. Можно сделать класс адаптер, который будет просто оберткой (заглушкой) методов интерфейса TextWatcher, соответственно вы сможете просто переопределить нужный Вам метод. Вообще вам нужно все равно будет использовать какой-то интерфейс слушателя. Возможен еще такой вариант с OnFocusChangeListener. Данный интерфейс имеет только один метод onFocusChange(View v, boolean hasFocus), сюда передается булевая переменная, которая показывает, был ли измен фокус данного View.

Скрипт вывода товаров, очень долго грузится

Функции выборки товаров из базы: function result_to_array($result) { $res_array = array(); $count = 0; while( $row = $result->fetch_assoc() ) { $res_array[$count] = $row; $count++; } return $res_array; }
function get_product() { connect_db(); global $mysqli; $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC"); $result = result_to_array($result); return $result; } На самой странице все товары выводятся циклом foreach: $products = get_product();

html код
Проблема в том, что страница с товарами открывается ну очень долго, раньше просто на этой же самой странице делал запрос и выводил все через while, по скорости было ощутимо быстрее. Подскажите, что я делаю не так и почему так медленно работает скрипт?


Ответ

А много ли товаров? И можно оптимизировать конструкцию, убрав $count while( $row = $result->fetch_assoc() ) { $res_array[] = $row; } Перед выполнением кода и после выполнения добавьте microtime() function result_to_array($result) { $ra_start = microtime();
$res_array = array(); $count = 0; while( $row = $result->fetch_assoc() ) { $res_array[$count] = $row; $count++; }
$ra_end = microtime(); echo $ra_end - $ra_start; return $res_array; }
function get_product() { $gp_start = microtime();
connect_db(); global $mysqli; $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC"); $result = result_to_array($result);
$gp_end = microtime(); echo $gp_end - $gp_start; return $result; } На самой странице все товары выводятся циклом foreach: $products = get_product();
html код: По результатам сможете увидеть, какой кусок у Вас долго выполняется.

Как правильно строить диаграммы последовательности UML?

Есть некий вариант использования приложения пользователем. В приложение 3 компонента: поле ввода и 2 кнопки. Пользователь вводит текст, затем жмет клавишу подтверждения, а затем клавишу выхода.
Правильно ли я для данного случая смог сделать диаграмму последовательности или есть ошибки?
Пример интерфейса:

Пример диаграммы:


Ответ

Насколько я помню, диаграмму последовательности лучше применять для раскрытия последовательности функционирования однотипных объектов, например, объектов классов. В Вашем случае напрашивается использовать диаграмму действий (Activity Diagram). Так как есть внешняя среда - актер и внутренняя - система (кнопки, поле). Также в Вашем примере пропадает или очень невелик смысл типов стрелочек (вызовов). Но в целом, в качестве простого примера, сделано правильно. Вернитесь к определению? для чего используется диаграмма последовательности. Что касается замечаний: Неясно, почему Вы ждете ответа от текстового поля после ввода текста? Из практики: нижние объекты (прямоугольники) можно не указывать. Они уже есть вверху.

Неверное получение байтов на javaScript

На C# через BinaryWriter запаковываю int'овые значения в бинарный файл. Этот шаг выполняется отлично, но проблема в следующем: При загрузке этих данных через JavaScript я получаю строку через XMLHttpRequest, далее, для наглядности, формирую массив, элементы которого состоят из 4 байтов. var dat=http.responseText;
var bytes = []; for (var i = 0; i < dat.length; i+=4) { var arr='';
for(var l=3;l>=0;l--) { for(var j=7;j>=0;j--) arr+=dat.charCodeAt(i+3-l)>>j & 1; arr+=" "; }
bytes.push(arr);
}
console.log(bytes); В результате получаются искаженные данные, например, первые 4 байта в файле выглядят так в двоичном коде: 00011000 01100111 00000011 00000000 а javaScript получает их как 11111101 00001000 00000010 00000000 В чем причина? Дополнительные исследования: При записи в файлы поменял кодировку на Unicode, не знаю, как это объяснить, но теперь байты считываются правильно, кроме тех, у которых в старшем бите 1, тогда те полностью преобразовываются в 11111101


Ответ

Смотрели Sending and Receiving Binary Data? Не responseText, а response var byteArray = new Uint8Array(dat); Я не исследовал вопрос бинарных данных в JS пока, только собираюсь заняться, поэтому не ответ, а лишь догадки.