Sự khác biệt giữa các luồng và datagram trong lập trình mạng là gì?


Câu trả lời:


304

Một thời gian dài trước đây tôi đã đọc một sự tương tự tuyệt vời để giải thích sự khác biệt giữa hai. Tôi không nhớ mình đã đọc nó ở đâu nên rất tiếc là tôi không thể tin tưởng tác giả cho ý tưởng đó, nhưng dù sao tôi cũng đã bổ sung rất nhiều kiến ​​thức của mình vào sự tương tự cốt lõi. Vì vậy, ở đây đi:

Một ổ cắm luồng giống như một cuộc gọi điện thoại - một bên thực hiện cuộc gọi, các câu trả lời khác, bạn nói xin chào với nhau (SYN / ACK trong TCP), sau đó bạn trao đổi thông tin. Khi bạn đã hoàn tất, bạn nói lời tạm biệt (FIN / ACK trong TCP). Nếu một bên không nghe lời tạm biệt, họ thường sẽ gọi lại cho bên kia vì đây là một sự kiện bất ngờ; thông thường khách hàng sẽ kết nối lại với máy chủ. Có một đảm bảo rằng dữ liệu sẽ không đến theo thứ tự khác với bạn đã gửi và có một đảm bảo hợp lý rằng dữ liệu sẽ không bị hỏng.

Một socket datagram giống như chuyển một ghi chú trong lớp. Hãy xem xét trường hợp bạn không trực tiếp bên cạnh người mà bạn đang chuyển ghi chú đến; các lưu ý sẽ đi từ người này sang người khác. Nó có thể không đến đích và nó có thể được sửa đổi vào thời điểm nó đến đó. Nếu bạn chuyển hai ghi chú cho cùng một người, họ có thể đến theo thứ tự bạn không có ý định, vì lộ trình mà các ghi chú đi qua lớp học có thể không giống nhau, một người có thể không chuyển một ghi chú nhanh như người khác, v.v. .

Vì vậy, bạn sử dụng một ổ cắm luồng khi có thông tin theo thứ tự và nguyên vẹn là rất quan trọng. Giao thức truyền tệp là một ví dụ tốt ở đây. Bạn không muốn tải xuống một số tệp với nội dung của nó bị xáo trộn ngẫu nhiên và bị hỏng!

Bạn sẽ sử dụng ổ cắm datagram khi đơn hàng ít quan trọng hơn phân phối kịp thời (nghĩ rằng giao thức VoIP hoặc giao thức trò chơi), khi bạn không muốn chi phí cao hơn của luồng (đây là lý do tại sao DNS chủ yếu là giao thức datagram, để máy chủ có thể đáp ứng nhiều, nhiều yêu cầu cùng một lúc rất nhanh) hoặc khi bạn không quan tâm quá nhiều nếu dữ liệu đã đến đích.

Để mở rộng trên trường hợp VoIP / trò chơi, các giao thức như vậy bao gồm cơ chế đặt hàng dữ liệu của riêng họ. Nhưng nếu một gói bị hỏng hoặc bị mất, bạn không muốn đợi giao thức truyền phát (thường là TCP) để đưa ra yêu cầu gửi lại - bạn cần khôi phục nhanh chóng. TCP có thể mất tới vài phút để khôi phục và đối với các giao thức thời gian thực như chơi game hoặc VoIP thậm chí ba giây có thể không được chấp nhận! Sử dụng giao thức datagram như UDP cho phép phần mềm khôi phục từ sự kiện đó cực kỳ nhanh chóng, bằng cách bỏ qua dữ liệu bị mất hoặc yêu cầu lại sớm hơn TCP.

VoIP là một ứng cử viên tốt để đơn giản bỏ qua dữ liệu bị mất - một bên sẽ chỉ nghe thấy một khoảng cách ngắn, tương tự như những gì xảy ra khi nói chuyện với ai đó trên điện thoại di động khi họ tiếp nhận kém. Các giao thức chơi trò chơi thường phức tạp hơn một chút, nhưng các hành động được thực hiện thường là bỏ qua dữ liệu bị thiếu (nếu dữ liệu nhận được sau đó thay thế dữ liệu bị mất), yêu cầu lại dữ liệu bị thiếu hoặc yêu cầu cập nhật trạng thái hoàn chỉnh đảm bảo rằng trạng thái của máy khách đồng bộ với trạng thái của máy chủ.


3
Đơn giản là tuyệt vời để bao gồm các chi tiết của ĐỒNG HỒ.
LazerSharks

2
Ví dụ này, hoặc một ví dụ tương tự, là từ Giao diện lập trình Linux. Phiên bản 2010 chứa các ví dụ này trên các trang 1155 và 1159.
Josh

30

Ổ cắm luồng:

  • Kênh chuyên dụng & đầu cuối giữa máy chủ và máy khách.
  • Sử dụng giao thức TCP để truyền dữ liệu.
  • Đáng tin cậy và không mất mát.
  • Dữ liệu được gửi / nhận theo thứ tự tương tự.
  • Thời gian dài để khôi phục dữ liệu bị mất / nhầm

Ổ cắm dữ liệu:

  • Không dành riêng và kênh đầu cuối giữa máy chủ và máy khách.
  • Sử dụng UDP để truyền dữ liệu.
  • Không đáng tin cậy 100% và có thể mất dữ liệu.
  • Dữ liệu gửi / nhận đơn đặt hàng có thể không giống nhau.
  • Đừng quan tâm hoặc phục hồi nhanh chóng dữ liệu bị mất / nhầm.

Không phải dữ liệu được gửi theo cùng một thứ tự (không chỉ "tương tự")? I E. Sẽ không có ý nghĩa gì khi xây dựng cơ chế đặt hàng gói vào ổ cắm luồng
Matthew D. Scholefield

Các gói trong giao tiếp luồng được gửi và nhận theo thứ tự "tương tự" theo nghĩa là các gói đó KHÔNG được đảm bảo được gửi đến máy chủ nhận theo thứ tự, nhưng TCP tìm ra sự khác biệt, sắp xếp lại các gói khi chúng đến và yêu cầu bất cứ điều gì điều đó dường như đã bị lạc trên đường đi.
Alejandro Blasco

Điều đó có ý nghĩa. Có thể chỉ cần loại bỏ sự khác biệt đó và đặt nó bên dưới (vì nếu tôi hiểu chính xác, khi chỉ đề cập đến thứ tự các gói được gửi, trong cả hai trường hợp, thứ tự mà dữ liệu được gửi / nhận có thể không được giống nhau).
Matthew D. Scholefield

@Rick Chính xác hơn, các socket được gọi là điểm đầu cuối vì các giao thức truyền tải chịu trách nhiệm gửi tin nhắn đến một hoặc nhiều điểm cuối mạng.
Alejandro Blasco

0

Nếu đó là chương trình mạng tôi nghĩ bắt đầu từ socket sẽ là một khởi đầu tốt.
socket = ip + port
có ba loại
luồng socket (TCP, đặt hàng và phân phối được đảm bảo, không trùng lặp, không có ranh giới chiều dài hoặc char cho dữ liệu,
datagram hướng kết nối, đáng tin cậy, đồng thời) (UDP, dựa trên gói, không kết nối, datagram Giới hạn kích thước, dữ liệu có thể bị mất hoặc trùng lặp, không đảm bảo trật tự, không đáng tin cậy)
(truy cập trực tiếp vào giao thức lớp thấp hơn IP, ICMP)
Tôi không thấy bất kỳ quy tắc nghiêm ngặt nào đối với loại giao thức vận chuyển như ổ cắm nào phải sử dụng giao thức vận chuyển nào và độ tin cậy không nên nhầm lẫn vì UDP là có thể thực hiện được trong trường hợp cả hai đầu đều hoạt động.
Độ tin cậy liên quan nhiều hơn đến độ tin cậy của phân phối vì có kiểm tra số thứ tự bằng cách sử dụng TCP làm giao thức vận chuyển không tồn tại trong UDP. Tốt hơn là sử dụng trình phân tích giao thức mạng như wireshark tcpdump, v.v. để xem phần mềm của bạn đang làm gì chính xác; loại xác minh hoặc hợp nhất lý thuyết trên giấy với công việc của bạn trong hành động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.