Đặt thời gian chờ cho các hoạt động của ổ cắm


86

Khi tôi tạo một ổ cắm:

Socket socket = new Socket(ipAddress, port);

Nó ném ra một ngoại lệ, điều này là OK, vì địa chỉ IP không có sẵn. (Các biến kiểm tra ở đâu String ipAddress = "192.168.0.3"int port = 300.)

Vấn đề là: làm cách nào để đặt nó thành timeout cho socket đó?

Khi tôi tạo ổ cắm, làm cách nào để giảm thời gian trước khi tôi nhận được UnknownHostExceptionvà làm cho ổ cắm hết thời gian chờ?


10
@adrianboimvaser: Trong trường hợp đó, bạn nên gắn cờ là trùng lặp và để lại nhận xét trỏ đến trùng lặp, để người kiểm duyệt có thể đóng nó như vậy (bạn đã để lại nhận xét đó một năm trước - có lẽ bạn đã biết điều đó). Tôi sẽ bỏ phiếu cho việc đó ngay bây giờ, nhưng tôi không biết bản sao ở đâu!
Tom Anderson

1
Để tiếp tục xu hướng trả lời trễ nhiều năm, @EJP tiêu đề của câu hỏi này ít mơ hồ hơn nhiều so với câu trùng lặp mà bạn đã đề xuất
Isaac

@Isaac Và trên thực tế, nó không hề trùng lặp, đã rút lại nhận xét.
Marquis of Lorne,

(Lưu ý: Tôi đã tinh chỉnh các tittle là ít mơ hồ.)
Stephen C

Câu trả lời:


165

Thay vào đó hãy sử dụng hàm Socket()tạoconnect(SocketAddress endpoint, int timeout)phương thức .

Trong trường hợp của bạn, nó sẽ giống như sau:

Socket socket = new Socket();
socket.connect(new InetSocketAddress(ipAddress, port), 1000);

Trích dẫn từ tài liệu

connect

public void connect(SocketAddress endpoint, int timeout) throws IOException

Kết nối ổ cắm này với máy chủ với giá trị thời gian chờ được chỉ định. Thời gian chờ bằng 0 được hiểu là thời gian chờ vô hạn. Sau đó kết nối sẽ bị chặn cho đến khi được thiết lập hoặc xảy ra lỗi.

Thông số:

endpoint- SocketAddress
timeout- giá trị thời gian chờ được sử dụng tính bằng mili giây.

Ném:

IOException- nếu lỗi xảy ra trong quá trình kết nối
SocketTimeoutException- nếu hết thời gian chờ trước khi kết nối
IllegalBlockingModeException- nếu ổ cắm này có kênh được liên kết và kênh đang ở chế độ không chặn
IllegalArgumentException- nếu điểm cuối là rỗng hoặc là lớp con SocketAddress không được ổ cắm này hỗ trợ

Kể từ: 1,4


4
Điều này có thể làm giảm thời gian chờ cho ConnectException (nhưng không làm tăng thời gian chờ) và nó không ảnh hưởng đến thời gian chờ cho UnknownHostException mà OP tuyên bố rằng anh ta đang nhận được (mặc dù tôi không tin điều đó). Cũng lưu ý rằng Javadoc không chính xác khi nói rằng mặc định là vô cực. Nó không phải. Nền tảng có thời gian chờ mặc định khoảng một phút và không thể tăng thời gian chờ này.
Marquis of Lorne,

3
Ngay cả sau 4 năm, điều này vẫn hữu ích, đây phải là câu trả lời được chấp nhận.
Sharp Edge

4
Bây giờ là sau 5 năm và đó là câu trả lời tốt nhất tôi tìm thấy trên Internet .. Cảm ơn bạn
MBH

1
Điều quan trọng là gọi socket.setSoTimeout(timeoutMillis)thời gian chờ trong khi chặn các hoạt động IO.
Grey

43

Bạn không đặt thời gian chờ cho ổ cắm, bạn đặt thời gian chờ cho các hoạt động bạn thực hiện trên ổ cắm đó.

Ví dụ socket.connect(otherAddress, timeout)

Hoặc socket.setSoTimeout(timeout)để đặt thời gian chờ cho các read()hoạt động.

Xem: http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html


Vâng, trong trường hợp này nó cũng là một hoạt động, kết nối. Tôi không thể tìm thấy bất kỳ nơi nào nói rằng ctor này sử dụng thời gian chờ vô hạn mặc dù có vẻ như vậy.
sandos

3
@sandos Nó được nêu rõ ràng trong Javadoc cho kết nối (). Tuy nhiên nó cũng không chính xác. Thời gian chờ mặc định là thời gian chờ của nền tảng, khoảng một phút, không phải vô hạn và nó chỉ có thể được giảm bằng phương thức connect () này, không được tăng lên.
Marquis of Lorne,

lưu ý, socket.setSoTimeoutphải được gọi là SAU KHI connect, nếu không nó sẽ không có hiệu lực và các lần đọc sẽ không bao giờ hết thời gian. đây là một gotcha được ghi chép kém.
pstanton

19

Bạn có thể sử dụng giải pháp sau:

SocketAddress sockaddr = new InetSocketAddress(ip, port);
// Create your socket
Socket socket = new Socket();
// Connect with 10 s timeout
socket.connect(sockaddr, 10000);

Hy vọng nó giúp!


1
Như anh ta tuyên bố, nếu anh ta nhận được một UnknownHostException, nó sẽ xảy ra ở dòng đầu tiên, nơi không có thời gian chờ sửa đổi có hiệu lực.
Marquis of Lorne

Tuy nhiên, dòng đầu tiên không ném ra bất kỳ ngoại lệ nào. Từ tài liệu: "Sẽ cố gắng giải quyết tên máy chủ thành InetAddress. Nếu nỗ lực đó không thành công, địa chỉ sẽ bị gắn cờ là chưa được giải quyết"
ady

Trong trường hợp đó, nó sẽ được giải quyết bằng connect()phương pháp, nhưng không nằm trong tầm kiểm soát của thời gian chờ.
Marquis of Lorne

8

Bạn không thể kiểm soát thời gian chờ do UnknownHostException . Đây là thời gian DNS. Bạn chỉ có thể kiểm soát thời gian chờ kết nối với một máy chủ hợp lệ. Không có câu trả lời nào ở trên giải quyết chính xác điểm này.

Nhưng tôi thấy khó tin rằng bạn thực sự nhận được UnknownHostExceptionkhi bạn chỉ định địa chỉ IP thay vì tên máy chủ.

CHỈNH SỬA Để kiểm soát thời gian chờ DNS của Java, hãy xem câu trả lời này .


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.