2012-03-07 3 views
5

다음의 몇 줄의 코드를 사용하여 IP를 통해 외부 모뎀/라우터 (장치라고도 함)에 쓰고 읽습니다.Indy InputBuffer의 TCPClient 및 rogue 바이트

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

MsgStr은 내 장치로 보내는 텍스트가 포함 된 문자열 유형입니다. 버퍼는 TIdBytes로 선언됩니다. IOHandler.InputBufferIsEmpty가 ReadBytes를 호출하기 직전에 True를 반환하는지 확인할 수 있습니다.

첫 번째 10 바이트를 매우 구체적으로 받아 들일 것으로 기대합니다. 따라서 내 문자열을 보낸 후에받은 첫 번째 10 바이트에만 관심이 있습니다.

특정 장치와 통신 할 때 첫 번째 바이트가 으로 연결을 설정 한 후 처음으로 문자열을 보냈습니다.은 버퍼 출력에 불량 (임의) 바이트를 넣습니다. 뒤 따르는 바이트들은 정확합니다. 내가 수 있습니다 기대하고 있습니다

예를 들어 10 바이트 : # 6A1EF1090 # 3하지만 내가 할 입니다 # 6A1EF1090.. 이 예에서 나는 하나가되어서는 안되는 곳에서 정차합니다.

다시 보내려고하면 잘 작동합니다. (즉, 연결이 설정된 후 전송 된 두 번째 쓰기). 이상한 (나에게) 소켓 스니퍼를 사용하여 임의의 바이트가 반환되는 것을 보여주지 않는다. 내가 응답을 수신하고 무언가를 다시 보내려면 내 "서버"를 만들면 시간이 100 % 잘 작동합니다. 내 소프트웨어가 아닌 다른 소프트웨어와 같은 다른 소프트웨어는 장치와 잘 통신합니다 (물론 데이터 구문 분석 방법에 대해서는 잘 모릅니다).

내가 잘못 설정 한 이유는 이것이 연결을 설정 한 후 처음으로 쓰기를 사용할 때만 발생하기 때문입니다.

감사

편집

내가 델파이 7과 인디 10.5.8

UPDATE

확인을 사용하고 있습니다. 많은 테스트와 검토 끝에이 솔루션을 찾는 데 더 이상 익숙하지 않습니다. 나는 두 가지 주요 시나리오를 얻고있다. 1 - 수신 된 패킷의 시작 부분에 첫 번째 바이트 누락 및 2 - "소개"바이트. TIdLogEvent 및 TIdLogDebug를 사용하면 누락 된 바이트 또는 처음 소개 된 바이트가 적절하게 표시됩니다. 그래서 위의 내 ReadBytes 문은 인디가 생각하는 것 (내 의견으로는)을 일관되게 보여주고 있습니다.

또한 테스트하기 위해 ICS 구성 요소를 다운로드하여 설치했습니다. 불행하게도 (또는 다행스럽게도 당신이 그것을 어떻게 보느냐에 따라) 이것은 Indy와 같은 이슈를 보여주지 못했다. 첫 번째 바이트가 누락되지 않았거나 시작 부분에 소개 된 바이트가 표시되지 않았습니다. 그러나, 나는 단지 표면적 인 테스트만을 수행했다. 그러나 ICS는 아직 그것을 전혀 생산하지 않았지만 인디는 "거의 똑바로"행동을 만들어 낸다.

누구든지 관심있는 사람이라면 누구나 내가 액세스 할 수 있도록 공개 IP이므로 문제와 IP를 보여주는 작은 데모 응용 프로그램을 제공 할 수 있습니다. 그렇지 않다면 지금 당장해야만 할 것입니다. 나는 ICS가이 인스턴스에서 잘 작동 할 수 있고이 소켓 물건의 사용이 프로그램의 핵심 이었기 때문에 ICS로 전환하기를 꺼린다. 인디를 ICS로 완전히 대체해야하는 것은 불쾌 할 것이다.를 추가하는 대신 버퍼 컨텐츠를 교체

+0

AnsiString (sizeof (char) = 1)을 보내면 도움이 될 것입니다. – ComputerSaysNo

+1

어디에서 코드를 삽입 할 수 있습니까? 참고로 필자는 유니 코드를 사용하는 최신 델파이 버전을 사용하고 있다고 생각한 경우 사용하고있는 델파이 버전을 보여주기 위해 제 질문을 편집했습니다. – Jason

+0

태그를 사용하여 델파이 버전 – ComputerSaysNo

답변

3

마지막 매개 변수 (참)을

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

판독시킨다.

이렇게하려면 먼저 버퍼의 크기와 내용이 올바르게 설정되어 있어야합니다.

매개 변수가 거짓이면 지정된 바이트 수만큼 버퍼 내용이 대체됩니다.

+0

불행히도 False로 설정하면 아무런 차이가 없습니다. 또한 SetLength (Buffer, 10)와 True/False를 다양한 방법으로 조합하여 시도했지만, 그렇지 않은 경우 도움이되었습니다. 그러나 모든 후속 송/수신에 대해 True를 사용할 경우, 효과가 있었다면 놀랐을 것입니다 (행복 하긴하지만). :) – Jason

1

ReadBytes()는 버퍼에 불량 바이트를 주입하지 않기 때문에 사용자가 제공 한 내가 지금 주어진 제한된 정보 생각할 수있는 유일한 두 가지 가능성이 있습니다

  1. 정말에 따라 추가 바이트를 전송하는 장치 mj2008과 같은 초기 연결이 제안되었습니다. 패킷 스니퍼가이를 감지하지 못하면 TIdLogFile 또는 TIdLogEvent과 같이 TIdTCPClient에 Indy 자신의 TIdLog... 구성 요소 중 하나를 연결하여 실제로 TIdTCPClient이 소켓에서 수신중인 것을 확인하십시오.

  2. InputBuffer이 손상되어 같은 스레드에서 동시에 읽는 스레드가 있습니다. TIdTCPClient.Connected()에 대한 호출조차도 읽기를 수행합니다. 스레드를 사용하는 경우 동시에 여러 스레드에서 읽기를 수행하지 마십시오.

+0

고마워요. 나는 pt 1을 시도하고 그것이 어떤 통찰력을 제공하는지보고하고 다시보고 할 것이다. – Jason