เหตุใดข้อยกเว้น“ java.net.ConnectException: การเชื่อมต่อหมดเวลา” จึงเกิดขึ้นเมื่อ URL ขึ้น


86

ฉันได้รับConnectException: Connection timed outความถี่บางส่วนจากรหัสของฉัน URL ที่ฉันพยายามจะกดขึ้น รหัสเดียวกันใช้ได้กับผู้ใช้บางคน แต่ใช้ไม่ได้ ดูเหมือนว่าเมื่อผู้ใช้รายหนึ่งเริ่มได้รับข้อยกเว้นนี้พวกเขายังคงได้รับข้อยกเว้น

นี่คือการติดตามสแต็ก:

java.net.ConnectException: Connection timed out
Caused by: java.net.ConnectException: Connection timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.Socket.connect(Socket.java:516)
    at java.net.Socket.connect(Socket.java:466)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
    at sun.net.www.http.HttpClient.New(HttpClient.java:287)
    at sun.net.www.http.HttpClient.New(HttpClient.java:299)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:796)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:748)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:673)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:840)

นี่คือตัวอย่างจากรหัสของฉัน:

URLConnection urlConnection = null;
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
InputStream inputStream = null;

try {
    URL url = new URL(urlBase);
    urlConnection = url.openConnection();
    urlConnection.setDoOutput(true);

    outputStream = urlConnection.getOutputStream(); // exception occurs on this line
    outputStreamWriter = new OutputStreamWriter(outputStream);
    outputStreamWriter.write(urlString);
    outputStreamWriter.flush();
    inputStream = urlConnection.getInputStream();
    String response = IOUtils.toString(inputStream);
    return processResponse(urlString, urlBase, response);
} catch (IOException e) {
    throw new Exception("Error querying url: " + urlString, e);
} finally {
    IoUtil.close(inputStream);
    IoUtil.close(outputStreamWriter);
    IoUtil.close(outputStream);
}

7
โปรดทำเครื่องหมายหนึ่งคำตอบว่ายอมรับหากคุณแก้ไขปัญหาได้แล้ว :)
Tobias

คำตอบ:


84

การหมดเวลาการเชื่อมต่อ (สมมติว่าเป็นเครือข่ายท้องถิ่นและเครื่องไคลเอนต์หลายเครื่อง) โดยทั่วไปเป็นผลมาจาก

ก) ไฟร์วอลล์บางชนิดที่กินแพ็กเก็ตโดยไม่บอกผู้ส่งเช่น "ไม่มีเส้นทางไปยังโฮสต์"

b) การสูญเสียแพ็กเก็ตเนื่องจากการกำหนดค่าเครือข่ายที่ไม่ถูกต้องหรือสายเกิน

c) มีการร้องขอมากเกินไปในเซิร์ฟเวอร์มากเกินไป

d) เธรด / กระบวนการที่พร้อมใช้งานพร้อมกันจำนวนเล็กน้อยบนเซิร์ฟเวอร์ซึ่งนำไปสู่การดำเนินการทั้งหมด สิ่งนี้เกิดขึ้นโดยเฉพาะกับคำขอที่ใช้เวลานานในการเรียกใช้และอาจรวมกับ c)

หวังว่านี่จะช่วยได้


สิ่งที่ช่วยฉันในการแก้ไขข้อบกพร่องนี้คือการ ping เซิร์ฟเวอร์ที่ฉันส่งคำขอไป ฉันพบว่า URL ได้รับการแก้ไขเป็น IP สาธารณะแทนที่จะเป็น IP ส่วนตัวที่ฉันต้องการ การแมปใหม่ในไฟล์ / etc / hosts ได้รับอนุญาตเพื่อแก้ไขปัญหา ฉันกำลังเพิ่มความคิดเห็นในกรณีที่มีคนอื่นประสบปัญหาในลักษณะเดียวกัน
Bouramas

32

หาก URL ทำงานได้ดีในเว็บเบราว์เซอร์บนเครื่องเดียวกันอาจเป็นไปได้ว่าโค้ด Java ไม่ได้ใช้พร็อกซี HTTP ที่เบราว์เซอร์ใช้เพื่อเชื่อมต่อกับ URL


6

ข้อความแสดงข้อผิดพลาดระบุทั้งหมด: การเชื่อมต่อของคุณหมดเวลา ซึ่งหมายความว่าคำขอของคุณไม่ได้รับการตอบกลับภายในกรอบเวลา (ค่าเริ่มต้น) บางส่วน สาเหตุที่ไม่ได้รับการตอบกลับน่าจะเป็นหนึ่งใน:

ก) IP / โดเมนหรือพอร์ตไม่ถูกต้อง

b) IP / โดเมนหรือพอร์ต (เช่นบริการ) หยุดทำงาน

c) IP / โดเมนใช้เวลานานกว่าการหมดเวลาเริ่มต้นของคุณในการตอบสนอง

d) คุณมีไฟร์วอลล์ที่บล็อกคำขอหรือการตอบสนองในพอร์ตใด ๆ ที่คุณใช้

จ) คุณมีไฟร์วอลล์ที่บล็อกคำขอไปยังโฮสต์นั้น ๆ

f) การเข้าถึงอินเทอร์เน็ตของคุณไม่ทำงาน

g) เซิร์ฟเวอร์สดของคุณหยุดทำงานเช่นในกรณีของ "การเรียก API ที่เหลือ"

โปรดทราบว่า ISP ของคุณอาจมีไฟร์วอลล์และพอร์ตหรือการบล็อก IP


4

ฉันขอแนะนำให้เพิ่มเวลาหมดเวลาการเชื่อมต่อก่อนที่จะรับสตรีมเอาต์พุตดังนี้:

urlConnection.setConnectTimeout(1000);

โดยที่ 1,000 อยู่ในหน่วยมิลลิวินาที (1,000 มิลลิวินาที = 1 วินาที)


21
นั่นไม่ใช่การเพิ่มขึ้น แต่เป็นการลดระดับลงอย่างมาก โดยค่าเริ่มต้นจะอยู่ที่ประมาณหนึ่งนาทีและคุณไม่สามารถเพิ่มได้คุณสามารถลดได้เท่านั้น
user207421



1

นี่อาจเป็นปัญหา IPv6 (โฮสต์เผยแพร่ IPv6 AAAA-Address และโฮสต์ของผู้ใช้คิดว่าถูกกำหนดค่าสำหรับ IPv6 แต่ไม่ได้เชื่อมต่ออย่างถูกต้อง) นอกจากนี้ยังอาจเป็นปัญหาเครือข่าย MTU บล็อกไฟร์วอลล์หรือโฮสต์เป้าหมายอาจเผยแพร่ที่อยู่ IP ที่แตกต่างกัน (แบบสุ่มหรือขึ้นอยู่กับประเทศของผู้สร้าง) ซึ่งไม่สามารถเข้าถึงได้ทั้งหมด หรือปัญหาเครือข่าย similliar

คุณทำอะไรไม่ได้มากนอกจากตั้งค่าการหมดเวลาและเพิ่มข้อความแสดงข้อผิดพลาดที่ดี (โดยเฉพาะการพิมพ์ที่อยู่ที่แก้ไขของโฮสต์) หากคุณต้องการทำให้มีประสิทธิภาพมากขึ้นให้เพิ่มการลองใหม่ให้ลองใช้ที่อยู่ทั้งหมดแบบขนานและดูการแคชการแก้ปัญหาชื่อ (บวกและลบ) บนแพลตฟอร์ม Java


1

เหตุใดข้อยกเว้น“ java.net.ConnectException: การเชื่อมต่อหมดเวลา” จึงเกิดขึ้นเมื่อ URL ขึ้น

เนื่องจาก URLConnection (HttpURLConnection / HttpsURLConnection) ผิดพลาด คุณสามารถอ่านเกี่ยวกับเรื่องนี้ที่นี่และที่นี่ วิธีแก้ปัญหาของเรามีสองอย่าง:

a) ตั้งค่า ContentLength ผ่าน setFixedLengthStreamingMode

b) จับ TimeoutException ใด ๆ และลองอีกครั้งหากล้มเหลว


0

มีความเป็นไปได้ที่ IP / โฮสต์ของคุณถูกบล็อกโดยโฮสต์ระยะไกลโดยเฉพาะอย่างยิ่งหากคิดว่าคุณกดปุ่มแรงเกินไป


0

สาเหตุที่สิ่งนี้เกิดขึ้นกับฉันคือเซิร์ฟเวอร์ระยะไกลอนุญาตให้ใช้เฉพาะ IP ที่กำหนดเท่านั้น แต่ไม่ใช่ของตัวเองและฉันกำลังพยายามแสดงภาพจาก URL ของเซิร์ฟเวอร์ ... ดังนั้นทุกอย่างจะหยุดลงโดยแสดงข้อผิดพลาดการหมดเวลาที่คุณ มี ...

ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์อนุญาต IP ของตัวเองหรือคุณกำลังแสดงผลสิ่งต่างๆจาก URL ระยะไกลที่มีอยู่จริง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.