ConnectionTimeout กับ SocketTimeout


135

ฉันมีปัญหากับไลบรารีที่ฉันใช้ อาจเป็นห้องสมุดหรืออาจเป็นฉันใช้ผิด!

โดยทั่วไปเมื่อฉันทำสิ่งนี้ (หมดเวลาเป็นมิลลิวินาที)

_ignitedHttp.setConnectionTimeout(1);  // v short
_ignitedHttp.setSocketTimeout(60000);  // 60 seconds

ไม่มีการสร้างข้อยกเว้นการหมดเวลาและทำงานได้ดีอย่างไรก็ตามเมื่อฉันทำสิ่งต่อไปนี้

_ignitedHttp.setConnectionTimeout(60000);  // 60 seconds
_ignitedHttp.setSocketTimeout(1);          // v short

ฉันได้รับข้อยกเว้นซ็อกเก็ต

ดังนั้นคำถามของฉันคือทำไมฉันไม่สามารถจำลองข้อยกเว้นการเชื่อมต่อได้? ฉันเข้าใจความแตกต่างระหว่างซ็อกเก็ตและการหมดเวลาการเชื่อมต่อหรือไม่? ห้องสมุดอยู่ที่นี่ (ยังไม่เปิดตัวอย่างเป็นทางการ)

คำตอบ:


227

หมดเวลาการเชื่อมต่อเกิดขึ้นเฉพาะเมื่อเริ่มต้นการเชื่อมต่อ TCP ซึ่งมักเกิดขึ้นหากเครื่องระยะไกลไม่ตอบรับ ซึ่งหมายความว่าเซิร์ฟเวอร์ถูกปิดคุณใช้ชื่อ IP / DNS ผิดพอร์ตผิดหรือการเชื่อมต่อเครือข่ายไปยังเซิร์ฟเวอร์หยุดทำงาน

การหมดเวลาของซ็อกเก็ตมีไว้เพื่อตรวจสอบการไหลของข้อมูลที่เข้ามาอย่างต่อเนื่อง หากกระแสข้อมูลถูกขัดจังหวะสำหรับการหมดเวลาที่ระบุการเชื่อมต่อจะถือว่าหยุดทำงาน / เสีย แน่นอนว่าจะใช้ได้เฉพาะกับการเชื่อมต่อที่ได้รับข้อมูลตลอดเวลา

การตั้งค่าการหมดเวลาของซ็อกเก็ตเป็น 1 สิ่งนี้จะทำให้ต้องได้รับข้อมูลใหม่ทุก ๆ มิลลิวินาที (สมมติว่าคุณอ่านบล็อกข้อมูลอย่างชาญฉลาดและบล็อกมีขนาดใหญ่พอ)!

หากมีเพียงสตรีมที่เข้ามาเท่านั้นที่หยุดนิ่งนานกว่าหนึ่งมิลลิวินาทีคุณกำลังพบกับการหมดเวลา


1
คุณจะหมดเวลาการเชื่อมต่อได้หรือไม่หากเซิร์ฟเวอร์ไม่หยุดทำงาน แต่ไม่ว่าง? หรือว่าจะหมดเวลาซ็อกเก็ต?
Robert

9
ขึ้นอยู่กับ - หากการเชื่อมต่อ TCP ถูกสร้างขึ้นก่อนที่เซิร์ฟเวอร์จะโอเวอร์โหลดคุณจะได้รับข้อยกเว้นของซ็อกเก็ตมิฉะนั้นคุณจะได้รับข้อยกเว้นการเชื่อมต่อซึ่งบ่งชี้ว่าไม่สามารถสร้างการเชื่อมต่อ TCP ได้
Robert

2
เมื่อพิจารณาถึงความหน่วงแฝงที่สูงของเครือข่ายมือถือรุ่นเก่าแล้วการหมดเวลาการเชื่อมต่อจะต้องถูกตั้งค่าเป็นหลายวินาที (เช่น 10 วินาทีหรือดีกว่า 10,000 มิลลิวินาที) ฉันจะตั้งค่าการหมดเวลาของซ็อกเก็ตก็ต่อเมื่อคุณไม่ได้ใช้การเชื่อมต่อหลายตัวเนื่องจาก HTTP สามารถใช้การเชื่อมต่อซ้ำได้หลังจากการร้องขอ
Robert

1
นี่หมายความว่าหากคุณตั้งค่าระยะหมดเวลาของซ็อกเก็ต (เช่น 1 นาที) การเชื่อมต่อจะถูกฆ่าหลังจากไม่มีการใช้งาน 1 นาทีโดยที่ปกติจะใช้ซ้ำได้หากไม่ได้ตั้งค่าการหมดเวลาไว้
Robert

2
@Robert คุณไม่จำเป็นต้องได้รับข้อยกเว้นการเชื่อมต่อหากเซิร์ฟเวอร์ยุ่งเกินไป มันขึ้นอยู่กับแพลตฟอร์มบนแพลตฟอร์มเซิร์ฟเวอร์ การหมดเวลาอ่านซ็อกเก็ตไม่ฆ่าการเชื่อมต่อ มันทำให้เกิด SocketTimeoutException การเชื่อมต่อยังคงใช้งานได้หรือไม่เป็นการตัดสินใจที่แอปพลิเคชันจะต้องทำ ไม่มีอะไรเกี่ยวกับ API ที่บอกว่าคุณไม่สามารถลอง I / O บนซ็อกเก็ตได้อีก คำแถลงของคุณเกี่ยวกับการไม่ใช้การหมดเวลาหากคุณใช้การเชื่อมต่อหลายรายการไม่สมเหตุสมผล ข้อมูลที่ผิดมากเกินไปที่นี่
Marquis of Lorne

83

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

การหมดเวลาของซ็อกเก็ตคือการหมดเวลาเมื่อรอแต่ละแพ็กเก็ต เป็นความเข้าใจผิดทั่วไปว่าการหมดเวลาของซ็อกเก็ตคือการหมดเวลาในการรับการตอบกลับทั้งหมด ดังนั้นหากคุณมีการหมดเวลาของซ็อกเก็ต 1 วินาทีและการตอบสนองประกอบด้วยแพ็กเก็ต IP 3 แพ็กเก็ตโดยที่แต่ละแพ็กเก็ตการตอบกลับจะมาถึง 0.9 วินาทีสำหรับเวลาตอบสนองทั้งหมด 2.7 วินาทีก็จะไม่มีการหมดเวลา


3
ตกลง. 1. ดังนั้นเราสามารถพูดได้ว่า SocketTimeout จะเกิดขึ้นเมื่อมีการเชื่อมต่อแล้วเท่านั้น? 2. ถ้าไม่มีการไหลของข้อมูลเช่นบอกว่า 5 นาทีหลังจากได้รับ 3 แพ็คเก็ตจะเป็นอย่างไร? จะมีข้อยกเว้น SocketTimeout หรือไม่หลังจากได้รับแพ็กเก็ตที่ 3 แล้ว?
Saurabh Patil

2
@SaurabhPatil 1. ค่ะ ดูภาพรวมทางเทคนิคของวิกิพีเดียเกี่ยวกับโปรโตคอล HTTPเพื่อยืนยัน 2. เมื่อส่งข้อความสิ้นสุดแล้วไม่จำเป็นต้องมีข้อมูลเพิ่มเติมดังนั้นการหมดเวลาของซ็อกเก็ตจะไม่เกิดขึ้น ดูคำตอบนี้ได้ที่หัวข้อ
entpnerd

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