2009-06-25 24 views
9

Tôi sắp viết một giao thức tin nhắn đi qua một luồng TCP. Người nhận cần phải biết ranh giới thông điệp ở đâu.Viết giao thức luồng: Trường kích thước thư hoặc Dấu phân cách thư?

Tôi có thể gửi 1) tin nhắn có độ dài cố định, 2) trường kích thước để người nhận biết thông báo lớn như thế nào, hoặc 3) một trình kết thúc tin nhắn duy nhất (tôi đoán điều này không thể được sử dụng ở bất kỳ nơi nào khác trong thư) .

Tôi sẽ không sử dụng # 1 vì lý do hiệu quả.

Tôi thích # 2 nhưng liệu luồng có thể không đồng bộ hóa được không?

Tôi không thích ý tưởng # 3 vì nó có nghĩa là người nhận không thể biết kích cỡ của thông báo trước và cũng yêu cầu người kết thúc không xuất hiện ở đâu đó trong thư.

Với # 2, nếu có thể không đồng bộ, tôi có thể thêm người kết thúc hoặc tôi được đảm bảo không bao giờ bị đồng bộ miễn là chương trình người gửi có chính xác không? Có cần phải làm # 2 # 3?

Vui lòng cho tôi biết.

Cảm ơn, jbu

Trả lời

5

Bạn đang sử dụng giao thức TCP, việc phân phối gói tin là đáng tin cậy. Vì vậy, kết nối hoặc giảm, thời gian chờ hoặc bạn sẽ đọc toàn bộ tin nhắn. Vì vậy, tùy chọn # 2 là ok.

3

Tùy thuộc vào cấp độ bạn đang làm việc, số 2 thực sự không có vấn đề gì khi không đồng bộ (TCP có số thứ tự trong các gói và kết hợp lại luồng theo đúng thứ tự cho bạn nếu nó đến hết trật tự).

Vì vậy, # 2 có lẽ là đặt cược tốt nhất của bạn. Ngoài ra, việc biết kích thước tin nhắn sớm trong quá trình truyền sẽ giúp việc phân bổ bộ nhớ trên đầu nhận được dễ dàng hơn.

+0

_Ngoài ra, việc biết kích thước tin nhắn sớm trong quá trình truyền sẽ giúp phân bổ bộ nhớ dễ dàng hơn trên đầu nhận._ Một từ cẩn thận: Đảm bảo giới hạn số lượng bộ nhớ được cấp phát. Nếu không, bạn dễ bị tấn công DDoS với các gói tùy chỉnh có trường kích thước là 2^32-1 (hoặc lớn hơn số nguyên của bạn), nhanh chóng lấp đầy bộ nhớ của bạn. – Kenji

1

Nếu bạn đang phát triển cả mã truyền và nhận từ đầu, nó sẽ không bị tổn thương khi sử dụng cả tiêu đề và ký tự phân cách độ dài. Điều này sẽ cung cấp độ mạnh mẽ và phát hiện lỗi. Hãy xem xét trường hợp bạn chỉ sử dụng # 2. Nếu bạn viết một trường độ dài của N vào luồng TCP, nhưng cuối cùng gửi một thông điệp có kích thước khác với N, thì đầu nhận sẽ không biết gì tốt hơn và kết thúc nhầm lẫn.

Nếu bạn sử dụng cả # 2 và # 3, trong khi không rõ ràng, người nhận có thể có mức độ tin cậy cao hơn khi nhận được thông báo chính xác nếu nó gặp dấu phân cách sau khi sử dụng N byte từ luồng TCP. Bạn cũng có thể sử dụng dấu phân tách trong thư của mình một cách an toàn.

Hãy xem HTTP Chunked Transfer Coding để có ví dụ về thế giới thực về sử dụng cả # 2 và # 3.

2

Tôi đồng ý với sigjuice. Nếu bạn có trường kích thước, không phải là cần thiết để thêm dấu phân cách cuối và thư - tuy nhiên, đó là một ý tưởng hay. Có cả hai làm cho mọi việc mạnh mẽ hơn và dễ dàng hơn để gỡ lỗi.

Cân nhắc sử dụng tiêu chuẩn netstring format, bao gồm cả trường kích thước và cũng là ký tự kết thúc chuỗi. Bởi vì nó có một trường kích thước, nó là OK cho ký tự kết thúc chuỗi được sử dụng bên trong tin nhắn.

0

Có giải pháp thay thế thứ tư: giao thức tự mô tả như XML.

+0

Điều này không phù hợp với các thông điệp nhị phân thuần túy. Về cơ bản nó là lựa chọn # 3 nhưng tệ hơn nhiều so với một dấu phân tách đơn. – Lucretiel

2

Thú vị không có câu trả lời rõ ràng ở đây. # 2 là an toàn trên TCP không có vấn đề gì, và được thực hiện "trong thế giới thực" khá thường xuyên. Điều này là do TCP đảm bảo rằng tất cả dữ liệu đến cả hai không bị hỏng và theo thứ tự mà nó đã được gửi, do đó, không có khả năng là việc triển khai chính xác có thể bị mất đồng bộ.