2012-03-07 26 views
5

Tôi đang sử dụng một vài dòng mã sau đây để viết và đọc từ một Modem/Router bên ngoài (aka thiết bị) qua IP.Tồn tại byte TCPClient và rogue trong InputBuffer

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

msgstr là một loại chuỗi mà chứa văn bản mà tôi đang gửi đến điện thoại của tôi. Bộ đệm được khai báo là TIdBytes. Tôi có thể xác nhận rằng IOHandler.InputBufferIsEmpty trả về True ngay trước khi gọi ReadBytes.

Tôi hy vọng 10 byte đầu tiên nhận được rất cụ thể do đó từ quan điểm của tôi, tôi chỉ quan tâm đến 10 byte đầu tiên nhận được sau khi tôi đã gửi chuỗi của mình.

Sự cố tôi gặp phải khi nói chuyện với một số thiết bị nhất định, byte đầu tiên trả về lần đầu tiên tôi gửi chuỗi sau khi thiết lập kết nối đặt byte ngẫu nhiên trong đầu ra Bộ đệm của tôi. Các byte tiếp theo sau là chính xác.

ví dụ 10 byte tôi hy vọng có thể là: # 6A1EF1090 # 3 nhưng những gì tôi nhận được là # 6A1EF1090.. trong ví dụ này, tôi có một điểm dừng đầy đủ, nơi không nên có một.

Nếu tôi cố gắng gửi lại, nó hoạt động tốt. (tức là Viết thứ 2 được gửi sau khi kết nối được thiết lập). Có gì lạ (với tôi) đang sử dụng một Socket Sniffer không hiển thị byte ngẫu nhiên được trả về. Nếu tôi tạo "máy chủ" của riêng mình để nhận được phản hồi và gửi lại một cái gì đó thì nó hoạt động tốt 100% thời gian. Các phần mềm khác - tức là, không phải phần mềm của tôi - giao tiếp tốt với thiết bị (nhưng tất nhiên tôi không biết chúng phân tích cú pháp dữ liệu như thế nào).

Có điều gì mà tôi đang làm không chính xác ở trên sẽ gây ra điều này - nhớ rằng nó chỉ xảy ra lần đầu tiên tôi sử dụng Viết sau khi thiết lập kết nối?

Cảm ơn

EDIT

Tôi đang sử dụng Delphi 7 và Indy 10.5.8

CẬP NHẬT

Ok. Sau nhiều lần thử nghiệm và tìm kiếm, tôi không tiến gần hơn đến việc tìm ra giải pháp này. Tôi nhận được hai kịch bản chính. 1 - byte đầu tiên bị thiếu và 2 - byte "được giới thiệu" khi bắt đầu gói tin nhận được. Sử dụng TIdLogEvent và TIdLogDebug cả hai đều hiển thị byte bị thiếu hoặc byte được giới thiệu ban đầu khi thích hợp. Vì vậy, tuyên bố ReadBytes của tôi ở trên là hiển thị một cách nhất quán những gì Indy tin là có (theo ý kiến ​​của tôi).

Ngoài ra, để kiểm tra thêm, tôi đã tải xuống và cài đặt các thành phần ICS. Thật không may (hoặc may mắn thay tùy thuộc vào cách bạn nhìn vào nó) điều này đã không hiển thị các vấn đề tương tự như Indy. Điều này không hiển thị byte đầu tiên bị thiếu hoặc cũng không hiển thị byte được giới thiệu ở đầu. Tuy nhiên, tôi chỉ thực hiện thử nghiệm bề ngoài, nhưng Indy tạo ra hành vi "khá nhiều ngay lập tức" trong khi ICS chưa tạo ra nó.

Nếu có ai quan tâm, tôi có thể cung cấp một ứng dụng demo nhỏ minh họa sự cố và IP mà tôi kết nối với - đó là IP công khai để mọi người có thể truy cập. Nếu không, bây giờ, tôi sẽ phải làm việc xung quanh nó. Tôi miễn cưỡng để chuyển sang ICS như ICS có thể làm việc tốt trong trường hợp này và cho việc sử dụng các công cụ ổ cắm này là khá nhiều toàn bộ điểm then chốt của chương trình, nó sẽ là khó chịu để có hoàn toàn thay thế Indy với ICS.

+0

thử gửi AnsiString (sizeof (char) = 1), có thể giúp – ComputerSaysNo

+1

Tôi sẽ đặt mã đó ở đâu? FYI, tôi đã chỉnh sửa câu hỏi của mình để hiển thị các phiên bản Delphi mà tôi đang sử dụng trong trường hợp bạn nghĩ rằng tôi đang sử dụng các phiên bản Delphi sau đó sử dụng Unicode. – Jason

+0

bạn nên sử dụng thẻ để chỉ định phiên bản delphi – ComputerSaysNo

Trả lời

3

Tham số cuối cùng (True)

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

làm cho đọc để thêm thay vì thay thế nội dung đệm.

Điều này yêu cầu kích thước và nội dung của bộ đệm được thiết lập chính xác trước.

Nếu tham số là False, nội dung bộ đệm sẽ được thay thế cho số byte nhất định.

+0

tiếc là đặt nó thành False sẽ không tạo ra sự khác biệt - nếu đó là ý của bạn. Tôi cũng đã thử kết hợp khác nhau của SetLength (Buffer, 10) với True/False quá trong trường hợp đó đã giúp mà nó không. Nhưng nếu True làm việc cho mỗi lần gửi/nhận tiếp theo, tôi sẽ rất ngạc nhiên (vui vẻ) nếu điều đó có hiệu quả. :) – Jason

1

ReadBytes() không tiêm byte giả mạo vào bộ đệm, vì vậy chỉ có hai khả năng tôi có thể nghĩ ngay bây giờ cho các thông tin hạn chế bạn đã cung cấp:

  1. Các thiết bị thực sự đang gửi một byte thêm vào kết nối ban đầu, như mj2008 được đề xuất. Nếu trình thám thính gói không phát hiện ra, hãy thử đính kèm một trong các thành phần TIdLog... của Indy vào số TIdTCPClient của bạn, chẳng hạn như TIdLogFile hoặc TIdLogEvent, để xác minh xem TIdTCPClient thực sự đang nhận được gì từ ổ cắm.

  2. bạn có một chuỗi đọc khác từ cùng một kết nối cùng một lúc, làm hỏng InputBuffer. Ngay cả một cuộc gọi đến TIdTCPClient.Connected() sẽ thực hiện đọc. Không thực hiện đọc trong nhiều chủ đề cùng một lúc, nếu bạn đang sử dụng các chủ đề.

+0

Cảm ơn. Tôi sẽ thử pt 1 và xem liệu nó có cung cấp thông tin chi tiết và báo cáo lại không. – Jason