Форум по Delphi программированию



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.10.2022, 11:34
Аватар для Electronic_Arts
Electronic_Arts Electronic_Arts вне форума
Местный
 
Регистрация: 13.07.2006
Адрес: на земле
Сообщения: 558
Версия Delphi: XE5
Репутация: 18
Восклицание Парсинг данных через COM порт

Всем привет мужики тише лет не заходил сюда забросил как то я дельфи. Вот опять поменял работу пытаюсь себе жизнь упростить.



Код:
2022-10-18 12:19:55: 
     Sim900_Write-81: 
     AT Send, len is 4 AT

2022-10-18 12:19:55: 
     Modul
[12:19:32.644]IN¡û¡ôe_Wait_Sync-373: 
     AT Recv, len is 9 AT
OK

2022-10-18 12:19:55: 
     Sim900_Write-81: 
     AT Send, len is 6 ATE0

[12:19:32.675]IN¡û¡ô
2022-10-18 12:19:55: 
     Module_Wait_Sync-373: 
     AT Recv, len is 11 ATE0
OK

2022-10-18 12:19:55: 
     Sim900_Write-81: 
[12:19:32.723]IN¡û¡ô
     AT Send, len is 19 AT+CNMI=0,0,0,0,0

[12:19:32.754]IN¡û¡ô
2022-10-18 12:19:55: 
     Module_Wait_Sync-373: 
     AT Recv, len is 6 
OK

2022-10-18 12:19:55: 
     Sim900_Write-81: 
     AT Send, len is 11 AT+CMGF=0

[12:19:32.817]IN¡û¡ô
2022-10-18 12:19:55: 
     Module_Wait_Sync-373: 
     AT Recv, len is 6 
OK

2022-10-18 12:19:55: 
     Sim900_Write-81: 
     AT Send, len is 12 AT+CIURC=0

[12:19:32.880]IN¡û¡ô
2022-10-18 12:19:55: 
     Module_Wait_Sync-373: 
     AT Recv, len is 6 
OK

2022-10-18 12:19:55: 
     Sim900_Write-81: 
     AT Send, len is 9 AT+CGMR

[12:19:32.944]IN¡û¡ô
2022-10-18 12:19:55: 
     Module_Wait_Sync-373: 
     AT Recv, len is 35 
Revision:1418B06SI
     M800C24

OK

2022-10-18 12:19:55: 
     Sim900_Write-81: 
     AT Send, len is 5 ATI

[12:19:33.023]IN¡û¡ô
2022-10-18 12:19:56: 
     Module_Wait_Sync-373: 
     AT Recv, len is 23 
SIM800 R14.18

O
     K

2022-10-18 12:19:56: 
     Sim900_Write-81: 
     AT Send, len is 9 AT+CGSN

[12:19:33.094]IN¡û¡ô
2022-10-18 12:19:56: 
     Module_Wait_Sync-373: 
     AT Recv, len is 25 
868895056178897


Вот такую информацию и много другой информации аппарат посылает по ком порту - если посмотрите там в одну секунду несколько пакетов данных идут. До добавления их в Memo я могу перехватить данные и парсить информацию.



В чем следовательно проблема. Перехвачиваю информацию я методом POS например

Код:
ansipos('AT+CGSN', text); //запрос на получения IMEI устройства

Из за того что пакетов много в одной секунде если например я перехватил отправленный пакет не могу перехватывать его результать.
Ответ идет следующим пакетом которую тупо пропускает обработчик.


Остановить поток данных нет возможности.
Как это можно решить?


Еще обратил внимание на то что если после перехвата будет много операций для извлечения результата то рушется последовательность.

Потому что пока идет обработка первого пакета там немаверной скоростью добавляются другие пакеты в строки TMemo
__________________
Нет ничего не возможного. Вопрос только во времени...
Ответить с цитированием
  #2  
Старый 23.10.2022, 11:36
Аватар для Electronic_Arts
Electronic_Arts Electronic_Arts вне форума
Местный
 
Регистрация: 13.07.2006
Адрес: на земле
Сообщения: 558
Версия Delphi: XE5
Репутация: 18
По умолчанию

OFFTOP

Дата регистрации 2006й год а вернулся в 2022ом
__________________
Нет ничего не возможного. Вопрос только во времени...
Ответить с цитированием
  #3  
Старый 24.10.2022, 20:02
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,868
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

не понятно, что ты пытаешься сделать.
Но, по тому, что ты описал, тебе, фактически, надо организовать что-то типа ассинхронной обработки.
Т.е. ты посылаешь некоторый запрос. Когда придет ответ ты точно не знаешь (и придет ли он вообще ). Тогда тебе надо сохранить где-то информацию о посланном запросе. Обработчик сообщений от девайса на самом деле должен просто складывать полученную информацию в некоторый буфер. А, например, отделный поток будет этот буфер читать и искать в нем ответы на посланные запросы. Как только ответ найден, он должен сохранить его и сгененрировать соотв. событие для главного потока, по которому тот поймет, что ответ получен и надо его вывести на экран (в соотв. компоненты).
Немного сумбурно, но, надеюсь, понятно. По представленной информации не понятно как можно "скрестить" запрос с ответом, так что с конкретикой в этот раз не получится. Но общий алгоритм я описал...
Ответить с цитированием
  #4  
Старый 24.10.2022, 21:58
Аватар для Electronic_Arts
Electronic_Arts Electronic_Arts вне форума
Местный
 
Регистрация: 13.07.2006
Адрес: на земле
Сообщения: 558
Версия Delphi: XE5
Репутация: 18
Восклицание

Мужик ты не представляешь как я рад снова видеть тебя тут.

- Нет. Вот представь два устройства которые общаются между собой по и я тот кто подключился к этой сети и перехватываю зашифрованные данные и нужно их дешифровать грубо говоря.
Вот например: Первый девайс посылает второму запрос что бы узнать IMEI и я перехватил этот запрос и начал обработку.
Text:=Comport.ReadAnsiString; //Пакет данных

Код:
2022-10-18 12:19:56: 
     Sim900_Write-81: 
     AT Send, len is 9 AT+CGSN
if pos('AT+CGSN', Text)<>0 then
//вот тут должен уже получить IMEI
А имеи придет в следующем пакете в форме в следующем цикле для меня а если смотреть на время ответ приходит в эту же секунду
Код:
2022-10-18 12:19:56: 
     Module_Wait_Sync-373: 
     AT Recv, len is 25 
868895056178897
И как перехватывать и обрабатывать такие данные если в одной секунде приходят 10-30 пакетов. Возможности собрать а потом обработать нету потому что чем медлить тем больше информации накопиться и парсить будет не выгодно по времени. К примеру девайс уже отключился а мой софт еще даже дату не смог парсить ИМЕИ к примеру.


Я многое сейчас заново вспоминаю много времени прошло.
Мучают вопрос на которые сможешь только ты ответить.
1. Если после перехвата if pos('AT+CGSN', Text)<>0 then передать данные на обработку к другой процедуре она будет параллельно работать?


Вот например

Код:
Text:=Comport.ReadAnsiString;
if pos('AT+CGSN', Text)<>0 then
begin
 //парсим данные тут

end;

if pos('GSN', Text)<>0 then
begin
 //парсим данные тут

end;
if pos('CSQ', Text)<>0 then
begin
 //парсим данные тут

end;
или после перехвата передать данные процедуре
Код:
Text:=Comport.ReadAnsiString;
if pos('AT+CGSN', Text)<>0 then
begin
 AT_CGSN:=STRING(Text);
 AT_CGSN; //процедура

end;

if pos('GSN', Text)<>0 then
begin
 GSN:=STRING(Text); 

 GSN; //процедура
end;
if pos('CSQ', Text)<>0 then
begin
 CSQ:=STRING(Text); 

 CSQ; //процедура

end;
втором случае как бы передаем пакет процедуре идем дальше.
Какой из них быстрее или разницы не будет??
__________________
Нет ничего не возможного. Вопрос только во времени...
Ответить с цитированием
  #5  
Старый 24.10.2022, 23:07
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,868
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Перивет, да, давненько тебя не было...
Нет, передача в процедуру не дает параллельной обработки. Только потоки, только хардкор
Короче, я понял, ты, типа. перехватываешь общение. В принципе, это ничего из того, что я написал, не меняет. Твой перехватчик "сидит" в главном потоке и просто тупо вычитывает данные и сохраняет их в каком-то буфере по типу FIFO очереди. А второй поток читает этот буфер и парсит его. В таком случае у читателя нет задержки и он вычитывает все, а вот парсер в отдельном потоке уже может не торопять искать запросы и ответы на них и выдавать уже готовую инфу.

Сейчас посмотрел на лог. Ну, похоже, что все общение идет в режиме "запрос-ответ". Т.е. ридер будет собирать все в кучку, а парсер в отдельном потоке будет все это разбирать и выдвать уже готовый результат. Т.е. с точки зрения парсера это будет непрерывный поток данных.
Т.е. тебе надо
1. Добиться того, что бы читатель генерировал выходной, например текстовый, поток без сбоев на границах пакетов. И потом этот поток помещается (добавляется) в буферный TStringList.
2. Дополнительный поток (thread) читает этот буфер и парсит, если ответ еще не пришел, то поток просто ждет пока ридер не накидает ему данных.

Тут еще надо посмотреть как пиходят пакеты (одна строка и это ты ее на части бъешь или оно уже многострочное приходит). В зависимости от этого и надо будет проектировать и ридер и парсер. Хотя, если ридер обеспечит нормальный текстовы поток, то парсер уж тогда простой получится. Типа читаем строку, если в ней есть "AT Send" то пошла команда, начинаем парсить команду, далее ждем пока не найдем строку с "AT Recv", там на следующих строках будет ответ пока не получим строку с "ОК" - все, парсинг закончен, выдаем событие в главный поток программы для вывода результата. Далее повторяем.

Только не забудь критические секции для доступа к буферу.
Ну и событие генерировать... даже не знаю как лучше сделать.
Может ридер тоже в отдельный поток "выкинуть", что бы главный поток со своими отрисовками и прочими действиями не тромозил его. И тогда парсер может вызывать событие главной формы сам, или вообще напрямую через Synchronize заполнять компоненты. А если нет, то можно посылать сообщение (PostMessage) и тогда оно попадет в очередь сообщений и будет обработано когда будет свободное время
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Electronic_Arts (25.10.2022)
  #6  
Старый 26.10.2022, 21:25
Аватар для Electronic_Arts
Electronic_Arts Electronic_Arts вне форума
Местный
 
Регистрация: 13.07.2006
Адрес: на земле
Сообщения: 558
Версия Delphi: XE5
Репутация: 18
Восклицание

А как в потоке сохранить ЛОГИ?
У меня выдает ошибку
Код:
---------------------------
Debugger Exception Notification
---------------------------
Project 123.exe raised exception class EFCreateError with message 'Cannot create file "C:\Logs\Log.txt". The process cannot access the file because it is being used by another process'.



Код:
procedure TSaveThread.Execute;
begin
  Form1.Memo1.PlainText := true;
  Form1.Memo1.Lines.SaveToFile('C:\Logs\Log.txt');
end;
__________________
Нет ничего не возможного. Вопрос только во времени...
Ответить с цитированием
  #7  
Старый 27.10.2022, 20:12
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,868
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

1. Проверь, что папка C:\Logs существует. SaveToFile не создает пути.
2. Проверь, что на папку C:\Logs даны все права, встречался с подобной проблеммой, надо просто тупо дать все права для Everyone.
3. Надо вызывать через Synchronize:
Код:
procedure TSaveThread.SaveLogs;
begin
  Form1.Memo1.PlainText := true;
  Form1.Memo1.Lines.SaveToFile('C:\Logs\Log.txt');
end;

procedure TSaveThread.Execute;
begin
  Synchronize(SaveLogs);
end;
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Electronic_Arts (28.10.2022)
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:23.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter   Ссылка на Telegram