|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
03.01.2015, 18:38 | #1 |
Пользователь
Регистрация: 20.03.2009
Сообщений: 99
|
работа с чужим протоколом передачи данных
Помогите пожалуста господа. Голову ломаю уже 3 день.
Есть чужой протокол передачи данных. Необходимо написать сервер который принимает эти данные. Вот небольшое описание протокола Первые 4 байта кол-во передаваемых пакетов - Integer, Затем 1 байт длина строки устройства - Byte Далее N(длина строки устройства) байт - id устройства - строка (может быть разной длины) Далее тип оборудования 1 байт - Byte Короче и тд. Примечание – при передаче нулевого количества пакетов пункт 2 пропускается, принимающая сторона сразу отвечает 0х55. (тоесть я должен отправить подтверждение) Таймауты Принимающая сторона должна ответить передающей стороне подтверждением 0х55 не позднее 5 секунд, после приема пакетов. Если принимающая сторона не успевает отправить подтверждение, то передающая сторона разорвет соединение и пошлет пакет заново. Рекомендуется обработку принятых сообщений делать асинхронно в отдельном потоке, чтобы процедуру общения с передающей стороной сделать без задержек. Пример передачи Передающая сторона: 00 00 00 00 //число пакетов – 0 Принимающая сторона: 55 // подтверждение приема, пропуск пункта 2 Передающая сторона: 01 00 00 00 //число пакетов – 1 Передающая сторона: 05 33 30 31 31 32 db 00 00 00 00 4b 71 00 e7 bc cd 08 2b 98 0a 42 89 06 66 42 33 33 97 42 41 01 b2 d0 ac 00 12 00 05 00 ca 00 4a 32 34 30 31 30 34 30 30 30 30 30 32 32 33 30 31 30 34 30 30 30 30 30 30 36 37 30 31 30 34 30 30 30 30 30 33 30 30 30 31 30 34 30 30 30 30 30 32 30 30 30 31 30 34 30 30 30 30 30 30 30 30 30 31 30 34 30 30 30 30 30 30 38 42 Принимающая сторона: 55 // подтверждение приема Вот в чем вопрос 1. Сервер передачи может отправить сразу несколько пакетов например F4 01 00 00 .............................. Что равно 500 пакетам за один раз передачи нам. 2.Между пакетами нет разделителей 3.При установлении соединения передающая сторона не отключается и при подтверждении шлет следующую кучу пакетов. Когда пакеты кончаются шлет просто 00 00 00 00 = 0 пакетов, а мы подтверждаем тем самым содинение установлено даже когда "не чего принимать" В чем сложность При приеме данных пакеты могут быть разбиты на несколько порций тоесть функцию recv нужно выполнять пока идут данные. А значит данные мы сможем принимать только непрерывным потоком при этом не зная где конец пакета, И в этот же самый момент их обрабатывать. Я пологаю нужно сделать так: принимаем порцию данных пишем в буфер отправляем буфер в функцию обработки пакета, функция обработки видит что в буфере должен быть 1 пакет данных, далее обрабатывает буфер данных до позиции в которой этот пакет заканчивается (это можно определить если читать байты по порядку). или возвращает результат о том что данных не достаточно и следует буфер дописать следующую порцию данных. Далее буфер снова попадает в функцию обработки и обрабатывается весь пакет, и функция возвращает результат о том что данные в буфере нужно сместить, или удалить те данные которые обработаны, а если есть новые сместить их в начало.(хотя я считаю что новых данных быть не должно пока я не отправлю подтверждение 0x55) Жесть... Что посоветуете я вобще правильно мыслю? |
03.01.2015, 19:09 | #2 |
Старожил
Регистрация: 03.01.2014
Сообщений: 2,870
|
А, размер пакета в протоколе указан? Может быть для указания размера предусмотрен особый фрагмент в "заголовке"?
|
03.01.2015, 19:17 | #3 |
Пользователь
Регистрация: 27.10.2011
Сообщений: 50
|
В моем понимании в любом случае должен быть указан размер принимаемого пакета. Иначе неразбериха в момент приема будет.
|
03.01.2015, 19:32 | #4 | |
Пользователь
Регистрация: 20.03.2009
Сообщений: 99
|
Цитата:
Например: 4a – поле data длиной 74 байта (может быть и не 74) 24 010400000223 010400000067 010400000300 010400000200 010400000000 01040000008B Расшифровываем 24 - это длина строки = 36 байт, 01 - это тип датчика, 04 длина строки Длина строки 36 байт, 6 датчиков, все типа 1, длиной 4 байта. Показания датчика 0 – 547 Показания датчика 1 – 103 Показания датчика 2 – 768 Показания датчика 3 – 512 Показания датчика 4 – 0 Показания датчика 5 – 139 Получается что пакеты могут быть разной длины |
|
03.01.2015, 19:37 | #5 | |
Пользователь
Регистрация: 20.03.2009
Сообщений: 99
|
Цитата:
Вот полное описание протокола. ну что есть какие идеи? вот так реализовал прием пакета Код:
Последний раз редактировалось Stilet; 08.01.2015 в 07:41. |
|
03.01.2015, 22:54 | #6 |
Старожил
Регистрация: 03.01.2014
Сообщений: 2,870
|
Из этого примера
следует, что длина сроки это и есть размер пакета, а дина строки, указанная в самом начале это суммарный размер всего сообщения. Полагаю, на это уже можно опереться. |
03.01.2015, 23:06 | #7 | |||||
Пользователь
Регистрация: 20.03.2009
Сообщений: 99
|
Это для поля Data вот с ним всё правильно организовано но
Data – поле дополнительных данных. Создается при необходимости передать значение больше 2 аналоговых входов. В случае отсутствия в поле Datalen передается 0. передаваемый пакет состоит так кол-во пакетов|длина следующей строки ID|ID строка|тип оборудования|дата и время|........|Длина поля Data|Data Поле Вот результат выполнения функции тут 3 пакета разом ппц FD_READ - установка длины буфера Функция требует еще данных, размер буфера будет увеличен на 348 Буфер увеличен и сейчас его размер 348 FD_READ - Прием данных в буфер... 03 00 00 00 06 32 32 35 30 30 33 0E 00 00 00 80 7B C9 26 A8 F5 D1 08 62 D6 82 42 BD 78 78 42 00 00 00 00 3D 00 00 00 00 00 00 00 07 00 C8 00 47 32 10 D0 83 25 00 C2 98 00 00 00 70 D0 82 15 00 00 00 00 00 D0 A0 D0 82 0B 00 00 00 00 00 D0 B0 D0 82 03 00 D0 91 6A 00 00 D1 80 D0 82 03 00 C2 BB 10 00 00 D1 80 D0 8F 21 00 00 00 00 00 00 D0 83 13 00 00 00 00 00 06 32 32 35 30 30 33 0E 00 00 00 80 1E AB 38 A8 F5 D1 08 62 D6 82 42 BD 78 78 42 00 00 00 00 3D 00 00 00 00 00 00 00 07 00 C8 00 47 32 10 D0 83 25 00 C2 98 00 00 00 70 D0 82 15 00 00 00 00 00 D0 A0 D0 82 0B 00 00 00 00 00 D0 B0 D0 82 03 00 D0 91 6A 00 00 D1 80 D0 82 03 00 C2 BB 10 00 00 D1 80 D0 8F 21 00 00 00 00 00 00 D0 83 13 00 00 00 00 00 06 32 34 39 34 34 33 0E 00 00 00 80 2F 8E 2B A8 F5 D1 08 E6 25 7F 42 F3 94 7B 42 00 00 00 00 00 00 00 00 00 00 00 00 07 00 D0 00 46 32 00 D0 83 13 00 00 00 00 00 D0 A0 D0 82 0B 00 00 00 00 00 10 D0 83 25 00 3E 00 00 00 D0 B0 D0 82 03 00 D1 80 5F 00 00 D1 80 D0 82 03 00 D0 98 10 00 00 D1 80 D0 8F 21 00 00 00 00 00 40 D0 82 06 00 46 05 00 00 Сервер остановлен смысл функции обработки пакета в том, что когда она начинает анализировать данные принятого (полностью или не полностью) пакета она понимает))) что в тут должно быть 10 пакетов данных, затем начинает их читать и наращивать счётчик пакетов, если этот счетчик не достигает конца или получается неожиданный конец буфера, то она возвращает значение и требует еще порцию данных событие FD_READ повторяется и дописывает еще данные. Передающая сторона всё равно не отправит следующие пакеты данных пока не придет подтверждение принятия предыдущих. вот капец извращенцы же есть. щас попробую накалякать её. Слушайте ребят помогите умоляю! уже запарился ей богу. Привет! Попробовал реализовать передачу данных по протоколу ScoutOpen всё впринципе хорошо, но непонятно следующее: Из приведенного вами примера описания протокола в базе знаний приводится пример передачи данных вот эта строка: Цитата:
Цитата:
далее в описании говорится что остальное это hex-строка тоесть представляем байты в строковом виде это получается так Цитата:
Цитата:
Цитата:
ЗЫ документация по работе с протоколом прикреплена в сообщении на 1 страницы данной темы. Последний раз редактировалось Stilet; 08.01.2015 в 07:41. |
|||||
07.01.2015, 23:03 | #8 |
Старожил
Регистрация: 03.01.2014
Сообщений: 2,870
|
А, в какой кодировке передаётся строка? В какой версии Delphi Вы работаете (начиная с 2009 формат string в Юникоде)?
|
07.01.2015, 23:48 | #9 | |
Пользователь
Регистрация: 20.03.2009
Сообщений: 99
|
Цитата:
и еще есть пример декодирования на C# Код:
Последний раз редактировалось Stilet; 08.01.2015 в 07:41. |
|
08.01.2015, 01:52 | #10 |
Заблокирован
Регистрация: 24.11.2014
Сообщений: 721
|
Передавайте пакеты не как строку, а как поток (TMemoryStream). Ещё советую попробовать вместо ClientSocket TWSocket от Overbyte. Там приём пакетов организован значительно проще. Не нужно вручную склеивать отдельные пакеты.
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Работа с протоколом ModBus (C++) | Olegvarmy | Помощь студентам | 21 | 19.09.2017 23:22 |
Delphi работа с протоколом sla | va-1 | Работа с сетью в Delphi | 1 | 07.05.2014 11:48 |
Работа с протоколом SIP в С++ | Mazorrmo | Общие вопросы C/C++ | 1 | 21.09.2008 22:21 |
Работа с протоколом GameSpy | Shouldercannon | Работа с сетью в Delphi | 8 | 08.03.2008 12:51 |
Работа с чужим приложением | ERASERROR | Win Api | 2 | 28.01.2008 15:22 |