2013-04-16 22 views
8

NIO và TCP tạo một cặp tuyệt vời cho nhiều kết nối. Vì một kết nối mới cần phải được mở cho mỗi máy khách mới, mỗi máy khách này thường sẽ cần chuỗi riêng của họ để chặn các hoạt động I/O. NIO giải quyết vấn đề đó bằng cách cho phép dữ liệu được đọc khi có thể, thay vì chặn cho đến khi nó có sẵn. Nhưng còn UDP thì sao?Điểm của việc sử dụng UDP với NIO là gì?

Ý tôi là, UDP không kết nối không có tính chất chặn của TCP được liên kết với nó do cách thức giao thức được thiết kế (gửi và quên nó, về cơ bản). Nếu tôi quyết định gửi một số dữ liệu đến một số địa chỉ, sau đó nó sẽ làm như vậy, mà không có sự chậm trễ (trên máy chủ). Tương tự như vậy, nếu tôi muốn đọc dữ liệu, tôi chỉ có thể nhận các gói dữ liệu riêng lẻ từ các nguồn khác nhau. Tôi không cần phải có nhiều kết nối đến nhiều nơi bằng nhiều chủ đề để đối phó với mỗi người.

Vậy, NIO và bộ chọn tăng cường UDP như thế nào? Cụ thể hơn, khi nào người ta thích sử dụng UDP với NIO hơn là gói ol 'java.net?

+0

Không phải là câu trả lời cho câu hỏi của bạn - nhưng trước tiên bạn nên kiểm tra xem NIO có nhanh hơn hay tốt hơn ngay cả đối với TCP - http://mailinator.blogspot.in/2008/02/kill-myth-please-nio-is-not -faster-than.html http://paultyma.blogspot.in/2008/03/writing-java-multithreaded-servers.html – user93353

Trả lời

8

Phương pháp DatagramSocket.receive(...) được ghi nhận là hoạt động chặn hoạt động. Vì vậy, ví dụ nếu bạn có một thread đang cố gắng xử lý các gói từ N socket khác nhau, bạn sẽ cần phải sử dụng NIO và selectors. Tương tự, nếu thread phải kiểm tra multiplex cho các gói mới với các hoạt động khác, bạn có thể làm điều này.

Nếu bạn không có những yêu cầu này hoặc tương tự, thì bộ chọn sẽ không giúp ích gì. Nhưng điều đó không khác gì với trường hợp TCP. Bạn không nên sử dụng bộ chọn với TCP nếu bạn không cần chúng, bởi vì nó khả năng thêm một cuộc gọi hệ thống bổ sung.

(Trên Linux, trong trường hợp gói tin, bạn muốn làm một syscall select theo sau là một recv ... thay vì chỉ một recv.)


Nhưng nếu bạn chỉ giao dịch với một DatagramSocket, sẽ không phải là phương pháp nhận đọc các gói ngay lập tức khi họ đến, bất kể thực tế là họ đang từ một máy tính khác nhau?

Nếu bạn đang nghe trên một ổ cắm cho datagram từ "mọi người" thì có. Nếu bạn có các ổ cắm khác nhau cho các máy tính khác nhau thì không.

Và đối với nhận xét TCP, đôi khi việc sử dụng công cụ chọn được đơn giản hóa bởi thực tế là rất cần tài nguyên để có hàng nghìn luồng, vì nó được yêu cầu bởi máy chủ TCP chặn.

Chúng tôi đã không thảo luận về trường hợp đó. Nhưng có, đó là sự thật. Và điều này cũng đúng nếu bạn có hàng ngàn luồng chặn trên UDP nhận được.

Quan điểm của tôi là nó, bạn không có rất nhiều chủ đề, hoặc nếu nó không quan trọng nếu một khối thread, sau đó nio không giúp. Trong thực tế, nó có thể làm giảm hiệu suất.

+0

Nhưng nếu bạn chỉ giao dịch với một DatagramSocket, sẽ không đọc phương thức 'receive' gói ngay lập tức khi chúng đến, bất kể thực tế là chúng từ một máy tính khác? Và đối với nhận xét TCP, đôi khi việc sử dụng một bộ chọn được biện minh đơn giản bởi thực tế là nó đòi hỏi rất nhiều tài nguyên để có hàng nghìn luồng, vì nó sẽ được yêu cầu bởi một máy chủ TCP chặn. –

+0

@MartinTuskevicius * Khi nào và nếu * họ đến. Nó vẫn là một hoạt động chặn. Nó cũng rất đòi hỏi tài nguyên để chuyển đổi lịch từ hệ điều hành sang ứng dụng thông qua một vòng lặp select(), và không nhất thiết phải công bằng. Bạn cần phải nhớ rằng select() được thiết kế trước khi các chủ đề đã tồn tại và thay thế là nhiều quá trình * * 1 cho câu trả lời này. – EJP

+0

vì vậy nếu tôi có một ổ cắm UDP ở phía máy chủ được nhiều khách hàng sử dụng, nó sẽ hiệu quả hơn khi sử dụng chặn IO và nhóm luồng chuyên dụng để xử lý các gói? – ka4eli

3

NIO loại bỏ sự cần thiết cho các chủ đề hoàn toàn. Nó cho phép bạn xử lý tất cả các máy khách của bạn trong một luồng, bao gồm cả máy khách TCP và UDP.

phi kết nối UDP không có tính chất ngăn chặn của TCP liên kết với nó

Đó không phải là sự thật. Nhận được vẫn còn khối, và do đó có thể gửi, ít nhất là trong lý thuyết.