|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Парсинг данных через 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
|
||||
|
||||
OFFTOP
Дата регистрации 2006й год а вернулся в 2022ом Нет ничего не возможного. Вопрос только во времени... |
#3
|
|||
|
|||
не понятно, что ты пытаешься сделать.
Но, по тому, что ты описал, тебе, фактически, надо организовать что-то типа ассинхронной обработки. Т.е. ты посылаешь некоторый запрос. Когда придет ответ ты точно не знаешь (и придет ли он вообще ). Тогда тебе надо сохранить где-то информацию о посланном запросе. Обработчик сообщений от девайса на самом деле должен просто складывать полученную информацию в некоторый буфер. А, например, отделный поток будет этот буфер читать и искать в нем ответы на посланные запросы. Как только ответ найден, он должен сохранить его и сгененрировать соотв. событие для главного потока, по которому тот поймет, что ответ получен и надо его вывести на экран (в соотв. компоненты). Немного сумбурно, но, надеюсь, понятно. По представленной информации не понятно как можно "скрестить" запрос с ответом, так что с конкретикой в этот раз не получится. Но общий алгоритм я описал... |
#4
|
||||
|
||||
Мужик ты не представляешь как я рад снова видеть тебя тут.
- Нет. Вот представь два устройства которые общаются между собой по и я тот кто подключился к этой сети и перехватываю зашифрованные данные и нужно их дешифровать грубо говоря. Вот например: Первый девайс посылает второму запрос что бы узнать IMEI и я перехватил этот запрос и начал обработку. Text:=Comport.ReadAnsiString; //Пакет данных Код:
2022-10-18 12:19:56: Sim900_Write-81: AT Send, len is 9 AT+CGSN //вот тут должен уже получить IMEI А имеи придет в следующем пакете в форме в следующем цикле для меня а если смотреть на время ответ приходит в эту же секунду Код:
2022-10-18 12:19:56: Module_Wait_Sync-373: AT Recv, len is 25 868895056178897 Я многое сейчас заново вспоминаю много времени прошло. Мучают вопрос на которые сможешь только ты ответить. 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
|
|||
|
|||
Перивет, да, давненько тебя не было...
Нет, передача в процедуру не дает параллельной обработки. Только потоки, только хардкор Короче, я понял, ты, типа. перехватываешь общение. В принципе, это ничего из того, что я написал, не меняет. Твой перехватчик "сидит" в главном потоке и просто тупо вычитывает данные и сохраняет их в каком-то буфере по типу FIFO очереди. А второй поток читает этот буфер и парсит его. В таком случае у читателя нет задержки и он вычитывает все, а вот парсер в отдельном потоке уже может не торопять искать запросы и ответы на них и выдавать уже готовую инфу. Сейчас посмотрел на лог. Ну, похоже, что все общение идет в режиме "запрос-ответ". Т.е. ридер будет собирать все в кучку, а парсер в отдельном потоке будет все это разбирать и выдвать уже готовый результат. Т.е. с точки зрения парсера это будет непрерывный поток данных. Т.е. тебе надо 1. Добиться того, что бы читатель генерировал выходной, например текстовый, поток без сбоев на границах пакетов. И потом этот поток помещается (добавляется) в буферный TStringList. 2. Дополнительный поток (thread) читает этот буфер и парсит, если ответ еще не пришел, то поток просто ждет пока ридер не накидает ему данных. Тут еще надо посмотреть как пиходят пакеты (одна строка и это ты ее на части бъешь или оно уже многострочное приходит). В зависимости от этого и надо будет проектировать и ридер и парсер. Хотя, если ридер обеспечит нормальный текстовы поток, то парсер уж тогда простой получится. Типа читаем строку, если в ней есть "AT Send" то пошла команда, начинаем парсить команду, далее ждем пока не найдем строку с "AT Recv", там на следующих строках будет ответ пока не получим строку с "ОК" - все, парсинг закончен, выдаем событие в главный поток программы для вывода результата. Далее повторяем. Только не забудь критические секции для доступа к буферу. Ну и событие генерировать... даже не знаю как лучше сделать. Может ридер тоже в отдельный поток "выкинуть", что бы главный поток со своими отрисовками и прочими действиями не тромозил его. И тогда парсер может вызывать событие главной формы сам, или вообще напрямую через Synchronize заполнять компоненты. А если нет, то можно посылать сообщение (PostMessage) и тогда оно попадет в очередь сообщений и будет обработано когда будет свободное время |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Electronic_Arts (25.10.2022)
|
#6
|
||||
|
||||
А как в потоке сохранить ЛОГИ?
У меня выдает ошибку Код:
--------------------------- 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
|
|||
|
|||
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)
|