ฉันสงสัยว่ามีวิธีสำรวจซ็อกเก็ตใน c# หรือไม่เมื่อตรงตามเงื่อนไขข้อใดข้อหนึ่งเท่านั้น (ข้อมูลที่มีให้อ่านได้) ฉันทราบถึงวิธี socket.Poll แต่สิ่งนี้ สามารถคืนค่าเป็นจริงได้หากเงื่อนไขทั้ง 3 ข้อที่ระบุคืนค่าเป็นจริงตามที่ระบุไว้ที่นี่: MSDN: Socket.Poll
มีวิธีสำรวจซ็อกเก็ตใน C # เฉพาะเมื่อมีบางสิ่งให้อ่านหรือไม่?
คำตอบ (6)
ตามเอกสารของ MSDN มีสาเหตุสามประการที่คืนค่าเป็นจริง
Poll(microSeconds, SelectMode.SelectRead);
- หาก
Listen()
ถูกเรียกและการเชื่อมต่ออยู่ระหว่างดำเนินการ - หากมีข้อมูลให้อ่าน
- หากการเชื่อมต่อถูกปิด รีเซ็ต หรือยุติ
มาดูกันว่าเราสามารถแยกแยะพวกเขาได้หรือไม่:
- คุณจะรู้อยู่เสมอว่าเคยถูกเรียก
Listen()
หรือไม่ ดังนั้นคุณไม่จำเป็นต้องพิจารณาถึงสาเหตุนั้น หากคุณไม่เคยถูกเรียก - โอเค คุณไปเพื่อสิ่งนั้น
- หมายความว่าคุณไม่สามารถอยู่ในการโทร Poll() ได้และจำเป็นต้องค้นหาว่าเกิดอะไรขึ้นจริง ทางเลือกหนึ่งคือตรวจสอบสถานะของซ็อกเก็ตทันทีหลังจากส่งคืน
Poll()
บทสรุป:
ไม่จำเป็นต้องได้รับการพิจารณา
และ 3. สามารถจัดการได้โดยการตรวจสอบสถานะซ็อกเก็ตทุกครั้งที่ส่งคืนค่าจริง
ดังนั้นฉันจะไปเพื่อ (ยังไม่ได้ทดสอบ):
if (s.Poll(microSeconds, SelectMode.SelectRead)))
{
if (!s.Connected)
// Something bad has happened, shut down
else
// There is data waiting to be read"
}
คุณสามารถใช้คุณสมบัติซ็อกเก็ตที่มีอยู่ มันจะส่งคืนจำนวนข้อมูลที่สามารถอ่านได้
พบบางสิ่งบางอย่างในคลาส NetworkStream คุณสมบัติ NetworkStream.DataAvailable ส่งคืนค่าจริง ถ้ามีข้อมูลให้อ่าน วัตถุของ networkstream ถูกส่งกลับโดยจัดการกับ TcpListener และ TcpClient นี่คือระดับนามธรรมที่สูงกว่าซ็อกเก็ตหนึ่งระดับ
ฉันไม่พบวิธีที่จะมาจาก Socket ไปยัง NetworkStream NetworkStream กำลังใช้ซ็อกเก็ตและเป็นตัวแทนสตรีมของซ็อกเก็ต แต่ฉันไม่รู้ว่ากระแสเครือข่ายกำลังทำอะไรอยู่ที่นั่นกับซ็อกเก็ต
คุณสามารถใช้การเรียกของระบบ select() บนจุดจับที่อยู่ด้านล่าง
คุณสามารถใช้วิธี Select() แทน Poll() จริงๆ แล้วเมื่อดูที่ Socket.Poll ด้วย ILSpy (เครื่องมือสะท้อนแสง) รหัสภายในกำลังเรียก select บนซ็อกเก็ต
นอกจากนี้ การเรียก Poll() แบบวนซ้ำจะเพิ่มการจัดสรรหน่วยความจำเนื่องจาก IntPtr[] ใหม่ในแต่ละการโทร การเรียก Select() ช่วยให้คุณสามารถนำอาร์เรย์กลับมาใช้ใหม่ได้ แทนที่จะจัดสรรอาร์เรย์ใหม่ภายใต้ประทุน
เป็นจริงหาก Listen ถูกเรียกและการเชื่อมต่ออยู่ระหว่างดำเนินการ -หรือ- จริงหากมีข้อมูลให้อ่าน -หรือ- จริงหากการเชื่อมต่อถูกปิด รีเซ็ต หรือยุติ มิฉะนั้นจะคืนค่าเท็จ
ฉันเข้าใจว่าคุณต้องการตรวจสอบว่าตัวเลือกที่สองคือตัวเลือกที่ส่งคืนจริงหรือไม่ หลังจากตรวจสอบว่า Poll คืนค่าเป็นจริงหรือไม่ คุณสามารถตรวจสอบว่าการเชื่อมต่อเปิดอยู่หรือไม่ นั่นหมายความว่า ไม่ใช่การเชื่อมต่อ ปิด รีเซ็ต หรือยุติ
หากเปิดอยู่ จะเป็นตัวเลือกที่สองที่คืนค่าเป็นจริง