2010-05-19 17 views
14

Tôi muốn sử dụng SocketChannel và để có thời gian chờ cho các phương pháp đọc/ghi của nó. Tôi đã cố gắng để thiết lập một thời gian chờ cho Socket sở hữu của tôi SocketChannel như thế này:Thời gian chờ cho SocketChannel không hoạt động

channel.socket().setSoTimeout(TIMEOUT); 

nhưng điều đó không làm việc. Còn có những giải pháp nào nữa ko?

+3

Thật không may, SocketChannel không hỗ trợ phương thức setSoTimeout trực tiếp. Sử dụng nó sẽ buồn bã được bỏ qua. – casey

+5

SocketChannel thực hiện giao diện InterruptibleChannel, có nghĩa là bạn có thể tạo một luồng riêng biệt trước khi nhập lệnh read() của bạn, có chủ đề khác đặt hẹn giờ và khi hết thời gian, nó có thể làm gián đoạn chuỗi trong đó SocketChannel của bạn đọc() cuộc gọi đang chặn. Nếu cuộc gọi read() trả về đầu tiên, bạn có thể khiến nó hủy chuỗi thời gian. –

+4

@StevensMiller Và kênh sẽ bị đóng và đọc sẽ ném 'ClosedByInterruptException.' Không hữu ích lắm. Tôi đã nói với việc thực hiện kỳ ​​lạ này được bắt buộc bởi hành vi của Linux. – EJP

Trả lời

14

Theo điều này article, SocketChannel sẽ không hết thời gian chờ thao tác đọc nhưng bạn có thể nhận được hiệu ứng này từ việc đọc từ kênh theo cách khác.

SocketChannel socketChannel; 
socketChannel.socket().setSocketTimeout(500); 
InputStream inStream = socketChannel.socket().getInputStream(); 
ReadableByteChannel wrappedChannel = Channels.newChannel(inStream); 

đọc từ góiChannel sẽ hết giờ theo socketTimeBạn đã đặt.

+0

giải pháp tốt. Java là ... bị mắc kẹt –

+1

Đây không phải là cách chính xác để thực hiện việc này, chỉ là giải pháp thay thế. Cách thích hợp là sử dụng Selector.select (timeout) trong một vòng lặp và kiểm tra soTimeout/connectTimeout với một if-check – wzona

+0

'setSocketTimeout' bây giờ là' setSoTimeout', nhưng hoạt động theo cùng một cách. –

-1

Bạn cũng có thể xem xét làm cho kênh của mình không thể chặn và chỉ sử dụng System.currentTimeMillis().

2

Nếu bạn đã quen với việc sử dụng Bộ chọn Java, bạn có thể mô phỏng thời gian chờ của ổ cắm bằng cách sử dụng bộ chọn. Thật hữu ích khi xem sun.nio.ch.SocketAdaptor.

Nên cẩn thận khi sử dụng Thread.interrupt(). SocketChannel là InterruptibleChannel. Khi bạn đọc mô tả của InterruptibleChannel, Thread.interrupt() gây ra cho đóng SocketChannel. Nếu bạn muốn sử dụng SocketChannel sau khi hết thời gian chờ, bạn không thể sử dụng tính năng InterruptibleChannel.

Các vấn đề liên quan