2012-03-07 2 views
5

Я использую следующие несколько строк кода для записи и чтения с внешнего модема/маршрутизатора (aka device) через IP.Indy TCPClient и байт-байт в InputBuffer

TCPClient.IOHandler.Write(MsgStr); 
TCPClient.IOHandler.InputBuffer.Clear; 
TCPClient.IOHandler.ReadBytes(Buffer, 10, True); 

MsgStr - это строковый тип, который содержит текст, который я отправляю на свое устройство. Буфер объявлен как TIdBytes. Я могу подтвердить, что IOHandler.InputBufferIsEmpty возвращает True непосредственно перед вызовом ReadBytes.

Я ожидаю, что первые 10 байтов будут очень точными, поэтому с моей точки зрения меня интересуют только первые 10 байт, полученные после того, как я отправил свою строку.

Проблема, с которой я столкнулся, когда разговаривает с определенными устройствами, первый байт возвратил при первом запуске строки после установления соединения. помещает баг в качестве буфера (случайного) в мой вывод буфера. Следующие последующие байты являются правильными.

например 10 байт Я ожидаю, что может быть: # 6A1EF1090 # 3 но то, что я получаю # 6A1EF1090.. в этом примере у меня есть полная остановка, где ее не должно быть.

Если я попытаюсь отправить снова, он отлично работает. (т.е. вторая запись, отправленная после установления соединения). Что странно (для меня) использует Socket Sniffer, не показывает возвращаемый случайный байт. Если я создаю свой собственный «сервер», чтобы получить ответ и отправить что-то обратно, он работает в 100% случаев. Другое программное обеспечение, то есть не мое программное обеспечение, прекрасно общается с устройством (но, конечно, я понятия не имею, как они анализируют данные).

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

Благодаря

EDIT

Я использую Delphi 7 и Indy 10.5.8

UPDATE

Ok. После долгих испытаний и поиска я не ближе к поиску этого решения. Я получаю два основных сценария. 1 - первый байт отсутствует и 2 - «введенный» байт в начале принятого пакета. Используя TIdLogEvent и TIdLogDebug, оба либо показывают отсутствующий байт, либо исходный введенный байт, если это необходимо. Таким образом, приведенное выше заявление ReadBytes показывает, что Indy полагает, что есть (на мой взгляд).

Кроме того, чтобы проверить его далее, я загрузил и установил компоненты ICS. К сожалению (или, к счастью, в зависимости от того, как вы на это смотрите) это не показало тех же проблем, что и Indy. Это не показало отсутствие первого байта и не показало введенный байт в начале. Тем не менее, я проверил только поверхностное тестирование, но Indy производит поведение «почти сразу», тогда как ICS еще не произвела его.

Если кому интересно, я могу предоставить небольшое демонстрационное приложение, иллюстрирующее проблему и IP-адрес, к которому я подключаюсь, - это общедоступный IP-адрес, чтобы любой мог получить к нему доступ. В противном случае, сейчас мне просто нужно будет обойти это. Я не хочу переключаться на ICS, так как ICS может работать нормально в этом случае, и, учитывая использование этого сокетного материала, в значительной степени является основной задачей программы, было бы противно полностью заменить Indy на ICS.

+0

попробуйте отправить AnsiString (sizeof (char) = 1), что может помочь – ComputerSaysNo

+1

Где я могу разместить этот код? FYI, я отредактировал свой вопрос, чтобы показать версии Delphi, которые я использую, если вы решили использовать более поздние версии Delphi, которые используют Unicode. – Jason

+0

Вы должны использовать теги, чтобы указать версию delphi – ComputerSaysNo

ответ

3

Последний параметр (True)

TCPClient.IOHandler.ReadBytes(Buffer, 10, True); 

вызывает чтение к добавить вместо замены содержимого буфера.

Для этого сначала необходимо правильно настроить размер и содержимое буфера.

Если параметр False, содержимое буфера будет заменено на заданное количество байтов.

+0

К сожалению, установка False не имеет значения - если это то, что вы имеете в виду. Я также пробовал различные комбинации SetLength (Buffer, 10) с True/False тоже в случае, если это помогло, чего не было. Но, учитывая истинные работы для каждой последующей отправки/получения, я был бы удивлен (к счастью, хотя бы), если бы это сработало. :) – Jason

1

ReadBytes() не вводить изгоев байт в буфер, так что есть только две возможности я могу думать сейчас данной ограниченной информации, которую вы предоставили:

  1. Устройство действительно посылает дополнительный байт UPoN начальное соединение, например, mj2008. Если пакетный снифер не обнаруживает его, попробуйте подключить один из компонентов TIdLog... от Indy к вашему TIdTCPClient, например TIdLogFile или TIdLogEvent, чтобы проверить, что TIdTCPClient действительно получает от сокета.

  2. У вас есть другая резьба, читающая одно и то же соединение одновременно, развращая InputBuffer. Даже вызов TIdTCPClient.Connected() будет выполнять чтение. Не выполняйте чтение в нескольких потоках одновременно, если вы используете потоки.

+0

Спасибо. Я попробую pt 1 и посмотрю, дает ли это понимание и отчет. – Jason

 Смежные вопросы

  • Нет связанных вопросов^_^