มีวิธีสำรวจซ็อกเก็ตใน C # เฉพาะเมื่อมีบางสิ่งให้อ่านหรือไม่?

ฉันสงสัยว่ามีวิธีสำรวจซ็อกเก็ตใน c# หรือไม่เมื่อตรงตามเงื่อนไขข้อใดข้อหนึ่งเท่านั้น (ข้อมูลที่มีให้อ่านได้) ฉันทราบถึงวิธี socket.Poll แต่สิ่งนี้ สามารถคืนค่าเป็นจริงได้หากเงื่อนไขทั้ง 3 ข้อที่ระบุคืนค่าเป็นจริงตามที่ระบุไว้ที่นี่: MSDN: Socket.Poll


person Dark Star1    schedule 08.08.2009    source แหล่งที่มา


คำตอบ (6)


ตามเอกสารของ MSDN มีสาเหตุสามประการที่คืนค่าเป็นจริง

Poll(microSeconds, SelectMode.SelectRead);

  1. หาก Listen() ถูกเรียกและการเชื่อมต่ออยู่ระหว่างดำเนินการ
  2. หากมีข้อมูลให้อ่าน
  3. หากการเชื่อมต่อถูกปิด รีเซ็ต หรือยุติ

มาดูกันว่าเราสามารถแยกแยะพวกเขาได้หรือไม่:

  1. คุณจะรู้อยู่เสมอว่าเคยถูกเรียก Listen() หรือไม่ ดังนั้นคุณไม่จำเป็นต้องพิจารณาถึงสาเหตุนั้น หากคุณไม่เคยถูกเรียก
  2. โอเค คุณไปเพื่อสิ่งนั้น
  3. หมายความว่าคุณไม่สามารถอยู่ในการโทร Poll() ได้และจำเป็นต้องค้นหาว่าเกิดอะไรขึ้นจริง ทางเลือกหนึ่งคือตรวจสอบสถานะของซ็อกเก็ตทันทีหลังจากส่งคืน Poll()

บทสรุป:

  1. ไม่จำเป็นต้องได้รับการพิจารณา

  2. และ 3. สามารถจัดการได้โดยการตรวจสอบสถานะซ็อกเก็ตทุกครั้งที่ส่งคืนค่าจริง

ดังนั้นฉันจะไปเพื่อ (ยังไม่ได้ทดสอบ):

if (s.Poll(microSeconds, SelectMode.SelectRead)))
{
  if (!s.Connected)
    // Something bad has happened, shut down
  else
    // There is data waiting to be read"
}
person Armin    schedule 09.08.2009
comment
ขอขอบคุณทุกท่านสำหรับการตอบรับของคุณ - person Dark Star1; 10.08.2009
comment
คุณควรตรวจสอบ Connected ก่อนที่จะเรียกโพลหรือโพลสำหรับ Write ก่อนอ่าน เนื่องจากนั่นคือสิ่งที่ Connected ทำภายใต้ประทุนอยู่แล้ว - person Jay; 26.05.2016

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

person Agg    schedule 09.08.2009

พบบางสิ่งบางอย่างในคลาส NetworkStream คุณสมบัติ NetworkStream.DataAvailable ส่งคืนค่าจริง ถ้ามีข้อมูลให้อ่าน วัตถุของ networkstream ถูกส่งกลับโดยจัดการกับ TcpListener และ TcpClient นี่คือระดับนามธรรมที่สูงกว่าซ็อกเก็ตหนึ่งระดับ

ฉันไม่พบวิธีที่จะมาจาก Socket ไปยัง NetworkStream NetworkStream กำลังใช้ซ็อกเก็ตและเป็นตัวแทนสตรีมของซ็อกเก็ต แต่ฉันไม่รู้ว่ากระแสเครือข่ายกำลังทำอะไรอยู่ที่นั่นกับซ็อกเก็ต

person Christian13467    schedule 08.08.2009
comment
NetworkStream ยังมี .CanRead และ .CanWrite ซึ่งฉันพบว่ามีประโยชน์มาก - person VoteCoffee; 24.01.2020

คุณสามารถใช้การเรียกของระบบ select() บนจุดจับที่อยู่ด้านล่าง

person Joshua    schedule 08.08.2009
comment
ความคิดแรกของฉันเหมือนกัน แต่ก็ไม่แน่ใจว่านี่คือความหมายของดาวมืดจริงๆ หรือไม่ - person Christian13467; 09.08.2009

คุณสามารถใช้วิธี Select() แทน Poll() จริงๆ แล้วเมื่อดูที่ Socket.Poll ด้วย ILSpy (เครื่องมือสะท้อนแสง) รหัสภายในกำลังเรียก select บนซ็อกเก็ต

นอกจากนี้ การเรียก Poll() แบบวนซ้ำจะเพิ่มการจัดสรรหน่วยความจำเนื่องจาก IntPtr[] ใหม่ในแต่ละการโทร การเรียก Select() ช่วยให้คุณสามารถนำอาร์เรย์กลับมาใช้ใหม่ได้ แทนที่จะจัดสรรอาร์เรย์ใหม่ภายใต้ประทุน

person oferbar    schedule 19.05.2014

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

ฉันเข้าใจว่าคุณต้องการตรวจสอบว่าตัวเลือกที่สองคือตัวเลือกที่ส่งคืนจริงหรือไม่ หลังจากตรวจสอบว่า Poll คืนค่าเป็นจริงหรือไม่ คุณสามารถตรวจสอบว่าการเชื่อมต่อเปิดอยู่หรือไม่ นั่นหมายความว่า ไม่ใช่การเชื่อมต่อ ปิด รีเซ็ต หรือยุติ

หากเปิดอยู่ จะเป็นตัวเลือกที่สองที่คืนค่าเป็นจริง

person Phoexo    schedule 08.08.2009
comment
ชอบ: if (m_sock.Poll(-1, SelectMode.SelectRead) && (m_sock.Connected == true)) ? - person Dark Star1; 09.08.2009