เบญเบดเบเปเบเบตเปเบเบฑเบเปเบเปเบเปเบฝเบเปเบเบเปเบเบฑเบเปเบงเบฅเบฒเบเบปเบเบเบฒเบเบเปเบญเบเบซเบเปเบฒเบเบตเป. เบซเบเบถเปเบเปเบเปเบเปเบเบเบญเบเบเบปเปเบเบเปเบเบญเบเบญเบดเบเปเบเบตเปเบเบฑเบ - UDP เบเบทเบเบเปเบฒเปเบเปเปเบเบเปเบญเบฑเบเบเบฅเบดเปเบเบเบฑเบเบเปเปเบเบฝเบเปเบเปเบชเบปเปเบเบเปเปเบกเบนเบเปเบฅเบฐเบเบฒเบเบญเบญเบเบญเบฒเบเบฒเบ, เปเบเปเบเบฑเบเบชเบฐเบซเบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป "peer-to-peer" เบฅเบฐเบซเบงเปเบฒเบ nodes เปเบเบทเบญเบเปเบฒเบ. เปเบเบทเปเบญเบเบเบฒเบเบเบฒเบเบญเบญเบเปเบเบเบเบตเปเบเปเบฒเบเบเบฒเบเบเบญเบเบกเบฑเบ, เปเบเปเบเบเบญเบเบเบตเปเบกเบตเบเบฒเบเบเปเบฒเปเบเปเบเบตเปเบเปเปเปเบเปเบงเบฒเบเปเบเบเปเบงเปเบเปเบญเบเบซเบเปเบฒเบเบตเป, เปเบเบงเปเบเบเปเปเบเบฒเบก, เบเปเปเบเบปเบเบเปเบญเบเบเบญเบเปเบเปเบเบเบญเบ, เปเบเบฑเปเบ: เบเบฒเบเบเบฒเบเบเบฒเบเบฎเบฑเบเบเบฐเบเบฑเบ, เบเปเปเปเบเปเบซเบฒเบเปเบเบเบธเบเบเปเบญเบ. เบเบปเบโเบเบงเบฒเบกโเบเบตเปโเบญเบฐโเบเบดโเบเบฒเบโเบเบฒเบโเบเบฐโเบเบดโเบเบฑเบโเบเบญเบโเบญเบฐโเบเบธโเบชเบฑเบโเบเบฒโเบเบฒเบโเบเบฑเบโเบชเบปเปเบโเบเบตเปโเบฎเบฑเบโเบเบฐโเบเบฑเบโเบเปเบฒเบ UDPโ.
เปเบเบทเปเบญเบซเบฒ:
เบงเบดเบเบต DisposeByTimeout ProcessPackets เบงเบดเบเบตเบเบฒเบ เบงเบดเบเบตเบเบฒเบเบฎเบฑเบ Packet เบชเบปเปเบเบงเบดเบเบตเบเบฒเบเบซเบธเปเบกเบซเปเป
เปเบเบปเปเบฒ
เบชเบฐเบเบฒเบเบฑเบเบเบฐเบเบฐเบเปเบฒเบเบปเปเบเบชเบฐเบเบฑเบเบเบญเบเบญเบดเบเปเบเบตเปเบเบฑเบเปเบเปเบชเบปเบกเบกเบธเบเบเบทเปเบเบเบตเปเบเบตเปเบขเบนเปเบเบฝเบงเบเบฑเบเปเบเบดเปเบเปเบเปเบฅเบฐ node เบกเบตเบเบตเปเบขเบนเป IP เบเบปเปเบงเปเบฅเบเปเบฅเบฐเปเบเบฑเบเปเบญเบเบฐเบฅเบฑเบเปเบฅเบฐเบชเบฒเบกเบฒเบเบชเบทเปเบชเบฒเบเปเบเบเบเบปเบเบเบฑเบ nodes เบญเบทเปเบเป. เปเบเบเบฑเบเบเบธเบเบฑเบเบญเบดเบเปเบเบตเปเบเบฑเบ, เปเบเบเบงเบฒเบกเปเบเบฑเบเบเบดเบ, เบกเบตเบชเบฐเบเบฒเบเบฑเบเบเบฐเบเบฐเบเปเบฒเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบ - เบเบทเปเบเบเบตเปเบซเบเบถเปเบเบเบญเบเบเบตเปเบขเบนเป IP เบเบปเปเบงเปเบฅเบเปเบฅเบฐเบซเบผเบฒเบเบเบทเปเบเบเบตเปเบเบตเปเบกเบตเบเบตเปเบขเบนเปเบชเปเบงเบเบเบปเบงเปเบเบทเปเบญเบเปเบงเปเบขเบนเปเบซเบฅเบฑเบเบญเบธเบเบฐเบเบญเบ NAT.
เบชเบฐเบเบฒเบเบฑเบเบเบฐเบเบฐเบเปเบฒเบเบญเบเบญเบดเบเปเบเบตเปเบเบฑเบเบเบตเปเปเบกเปเบเบเบทเบเบเปเบญเบเบเบฝเบเบเปเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบทเปเบชเบฒเบเบเบญเบเบฅเบนเบเบเปเบฒเบเบฑเบเปเบเบทเปเบญเบเปเบกเปเบเปเบฒเบ, เบเปเบญเบเบเบตเปเบฅเบนเบเบเปเบฒเบชเบฒเบกเบฒเบเบขเบนเปเปเบเปเบเบทเบญเบเปเบฒเบเบชเปเบงเบเบเบปเบง, เปเบฅเบฐเปเบเบทเปเบญเบเปเบกเปเบเปเบฒเบเบกเบตเบเบตเปเบขเบนเปเบเบปเปเบงเปเบฅเบ. เปเบเปเบกเบฑเบเบชเปเบฒเบเบเบงเบฒเบกเบซเบเบธเปเบเบเบฒเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบเบเบปเบเบเบญเบเบชเบญเบ nodes เบฅเบฐเบซเบงเปเบฒเบ เบเปเบฒเบ เปเบเบทเบญโเบเปเบฒเบโเบชเปเบงเบโเบเบปเบงโ. เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบเบเบปเบเบฅเบฐเบซเบงเปเบฒเบเบชเบญเบ nodes เปเบกเปเบเบชเปเบฒเบเบฑเบเบชเปเบฒเบฅเบฑเบเบเปเบฒเบฎเปเบญเบเบชเบฐเบซเบกเบฑเบ peer-to-peer เปเบเบฑเปเบเบเบฒเบเบชเบปเปเบเบชเบฝเบ (Skype), เบเบฒเบเปเบเบปเปเบฒเปเบเบดเบเบเบญเบกเบเบดเบงเปเบเบตเบเบฒเบเปเบฅเบเบฐเปเบ (TeamViewer), เบซเบผเบทเปเบเบกเบญเบญเบเปเบฅเบเป.
เบซเบเบถเปเบเปเบเบงเบดเบเบตเบเบฒเบเบเบตเปเบกเบตเบเบฐเบชเบดเบเบเบดเบเบฒเบเบเบตเปเบชเบธเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเปเบฒเบเบเบฑเปเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป peer-to-peer เบฅเบฐเบซเบงเปเบฒเบเบญเบธเบเบฐเบเบญเบเปเบเปเบเบทเบญเบเปเบฒเบเปเบญเบเบฐเบเบปเบเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบเปเบกเปเบเปเบญเบตเปเบเบงเปเบฒเบเบฒเบเปเบเบฒเบฐเบฎเบน. เปเบเบฑเบเบเบดเบเบเบตเปเบเบทเบเบเปเบฒเปเบเปเบซเบผเบฒเบเบเบตเปเบชเบธเบเบเบฑเบเบเปเบฒเบฎเปเบญเบเบชเบฐเบซเบกเบฑเบเปเบเบเบญเบตเบเปเบชเปเปเบเปเบเบเบญเบ UDP.
เปเบเปเบเปเบฒเบเปเบฒเบฎเปเบญเบเบชเบฐเบซเบกเบฑเบเบเบญเบเบเปเบฒเบเบเปเบญเบเบเบฒเบเบเบฒเบเบฎเบฑเบเบเบฐเบเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเปเปเบกเบนเบ, เบเบปเบงเบขเปเบฒเบ, เบเปเบฒเบเปเบญเบเปเบเบฅเปเบฅเบฐเบซเบงเปเบฒเบเบเบญเบกเบเบดเบงเปเบเบต, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบฒเบเบเปเบฒเปเบเป UDP เบเบฐเบกเบตเบเบงเบฒเบกเบซเบเบธเปเบเบเบฒเบเบซเบผเบฒเบเบญเบฑเบเปเบเบทเปเบญเบเบกเบฒเบเบฒเบเบเบงเบฒเบกเบเบดเบเบเบตเปเบงเปเบฒ UDP เบเปเปเปเบกเปเบเปเบเปเบเบเบญเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบตเปเบฎเบฑเบเบเบฐเบเบฑเบเปเบฅเบฐเบเปเปเบชเบฐเบซเบเบญเบเบเบฒเบเบเบฑเบเบชเบปเปเบเปเบเบฑเบเปเบเบฑเบ, เบเปเปเบเบทเบเบฑเบ TCP. เบเบดเบเบตเบเบฒเบ.
เปเบเบเปเบฅเบฐเบเบตเบเบตเป, เปเบเบทเปเบญเบฎเบฑเบเบเบฐเบเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบฎเบฑเบเบเบฐเบเบฑเบ, เบกเบฑเบเบเปเบฒเปเบเบฑเบเบเปเบญเบเบเบฐเบเบดเบเบฑเบเปเบเปเบเบเบญเบเบเบฑเปเบเบเปเบฒเบฎเปเบญเบเบชเบฐเบซเบกเบฑเบเบเบตเปเบชเบฐเบซเบเบญเบเบเบฒเบเปเบฎเบฑเบเบงเบฝเบเบเบตเปเบเปเบฒเปเบเบฑเบเปเบฅเบฐเปเบฎเบฑเบเบงเบฝเบเบซเบผเบฒเบเบเบงเปเบฒ UDP.
เบเปเบญเบเบเปเบญเบเบเบฒเบเบชเบฑเบเปเบเบเบเบฑเบเบเบตเบงเปเบฒเบกเบตเปเบเบฑเบเบเบดเบเบเบฒเบเปเบเบฒเบฐเบฎเบน TCP เบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเปเบฒเบเบเบฑเปเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป TCP เบฅเบฐเบซเบงเปเบฒเบ nodes เปเบเปเบเบทเบญเบเปเบฒเบเปเบญเบเบฐเบเบปเบเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบ, เปเบเปเปเบเบทเปเบญเบเบเบฒเบเบเบฒเบเบเบฒเบเบเบฒเบเบชเบฐเบซเบเบฑเบเบชเบฐเบซเบเบนเบเบกเบฑเบเปเบเบเบญเบธเบเบฐเบเบญเบ NAT เบซเบผเบฒเบ, เบกเบฑเบเบกเบฑเบเบเบฐเบเปเปเบเบทเบงเปเบฒเปเบเบฑเบเบงเบดเบเบตเบเบปเปเบเบเปเปเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป. เบเปเปเบเบฑเปเบเบเปเบฒเบง.
เบชเปเบฒเบฅเบฑเบเบชเปเบงเบเบเบตเปเปเบซเบผเบทเบญเบเบญเบเบเบปเบเบเบงเบฒเบกเบเบตเป, เบเปเบฒเบเบฐเปเบเบปเปเบฒเบเบฐเบชเบธเบกเปเบชเปเบเบฝเบเปเบเปเบเบฒเบเบเบฐเบเบดเบเบฑเบเบเบญเบเบญเบฐเบเบธเบชเบฑเบเบเบฒเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบตเปเบฎเบฑเบเบเบฐเบเบฑเบ. เบเบฒเบเบเบฐเบเบดเบเบฑเบเปเบเบฑเบเบเบดเบเบเบฒเบเปเบเบฒเบฐเบฎเบน UDP เบเบฐเบเบทเบเบญเบฐเบเบดเบเบฒเบเปเบงเปเปเบเบเบปเบเบเบงเบฒเบกเบเปเปเปเบเบเบตเป.
เบเปเปเบเปเบฒเบเบปเบเบเบดเบเบตเบเบฒเบ
- เบเบฒเบโเบเบฑเบโเบชเบปเปเบโเบเบญเบโเบเบตเปโเปเบเบทเปเบญโเบเบทโเปเบเปโเบเบฐโเบเบดโเบเบฑเบโเปเบเบโเบเปเบฒเบโเบเบปเบโเปเบโเบเปเบฒโเบเบถเบโเบเปเบฒโเปเบซเบฑเบโเปเบโเบเบฒเบโเบเบงเบ (เบญเบฑเบโเบเบตเปโเปเบญเบตเปเบโเบงเปเบฒโเบเบฒเบโเบฎเบฑเบโเบฎเบนเปโเปเบโเบเบฒเบโเบเบงเบโ)
- เบเบงเบฒเบกเบเปเบญเบเบเบฒเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเปเบญเบเบเปเปเบกเบนเบเปเบซเบเปเบเบตเปเบกเบตเบเบฐเบชเบดเบเบเบดเบเบฒเบ, i.e. เปเบเปเบเบเบญเบเบเปเบญเบเบซเบผเบตเบเปเบงเบฑเปเบเบเบฒเบเบชเบปเปเบเบเปเปเปเบเบฑเบเปเบเบฑเบเบเบตเปเบเปเปเบเปเบฒเปเบเบฑเบ
- เบกเบฑเบเบเบงเบเบเบฐเปเบเบฑเบเปเบเปเบเปเบเบตเปเบเบฐเบเบปเบเปเบฅเบตเบเบเบปเบเปเบเบเบฒเบเบขเบทเบเบขเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบ (เบเบงเบฒเบกเบชเบฒเบกเบฒเบเปเบเบเบฒเบเปเบฎเบฑเบเบงเบฝเบเปเบเบฑเบเปเบเปเบเบเบญเบ UDP "เบเปเบฅเบดเบชเบธเบ").
- เบเบงเบฒเบกเบชเบฒเบกเบฒเบเปเบเบเบฒเบเบเบฐเบเบดเบเบฑเบเบฎเบนเบเปเบเบเบเปเบฒเบชเบฑเปเบ, เบเปเบงเบเบเบฒเบเบขเบทเบเบขเบฑเบเบเบญเบเปเบเปเบฅเบฐเบเปเปเบเบงเบฒเบก
- เบซเบปเบงเปเปเบงเบเบเบทเปเบเบเบฒเบเบเบญเบเบเบฒเบเปเบญเบเบเปเปเบกเบนเบเบเปเบฒเบเปเบเบฃเปเบเบเปเบเปเบญเบเปเบเบฑเบเบเปเปเบเบงเบฒเบก
เบเปเปเบเปเบฒเบเบปเบเปเบซเบผเบปเปเบฒเบเบตเปเบชเปเบงเบเบซเบผเบฒเบเปเบกเปเบเบเบปเบเบเบฑเบเบเบฑเบเบเปเปเบเปเบฒเบเบปเบเบเบญเบเปเบเปเบเบเบญเบเบเปเปเบกเบนเบเบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเบเบตเปเปเบเปเบญเบฐเบเบดเบเบฒเบเปเบงเปเปเบ
เปเบเบทเปเบญเปเบเบปเปเบฒเปเบเบเบงเบฒเบกเบเปเบญเบเบเบฒเบเปเบซเบผเบปเปเบฒเบเบตเป, เปเบซเปเบเบงเบเปเบฎเบปเบฒเปเบเบดเปเบเปเบงเบฅเบฒเบเบญเบเบเบฒเบเปเบญเบเบเปเปเบกเบนเบเบฅเบฐเบซเบงเปเบฒเบเบชเบญเบเปเบซเบเบเปเบเบทเบญเบเปเบฒเบเปเบเบเปเบเปเปเบเปเบเบเบญเบ TCP เปเบฅเบฐ UDP. เปเบซเปเปเบเบเบฑเบเบชเบญเบเบเปเบฅเบฐเบเบต, เบเบงเบเปเบฎเบปเบฒเบเบฐเบชเบนเบเปเบชเบเบเบญเบเบซเบเบถเปเบ.
เบเบฒเบเปเบญเบเบเปเปเบกเบนเบเบเบตเปเบเปเปเบกเบตเบเบฒเบเปเบเปเบเบญเบเบเปเบฒเบ TCP:
เบเบฑเปเบเบเบตเปเปเบเบปเปเบฒเบชเบฒเบกเบฒเบเปเบซเบฑเบเปเบเปเบเบฒเบเปเบเบเบงเบฒเบ, เปเบเบเปเบฅเบฐเบเบตเบเบญเบเบเบฒเบเบชเบนเบเปเบชเบเปเบเบฑเบเปเบเบฑเบ, TCP เบเบฐเบเบงเบเบเบปเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบนเบเปเบชเบเปเบฅเบฐเบฅเบฒเบเบเบฒเบเปเบซเปเบเบนเปเบชเบปเปเบเปเบเบเบเบฒเบเบฎเปเบญเบเบเปเปเบซเปเบกเบตเบเปเบฒเบเบงเบเบชเปเบงเบเบเบตเปเบชเบนเบเปเบชเบ.
เบเบฒเบเปเบญเบเบเปเปเบกเบนเบเบเปเบฒเบ UDP Protocol:
UDP เบเปเปเปเบเปเบเปเบฒเปเบเบตเบเบเบฑเปเบเบเบญเบเบเบฒเบเบเบงเบเบชเบญเบเบเบฒเบเบชเบนเบเปเบชเบเปเบเป. เบเบฒเบเบเบงเบเบเบธเบกเบเบงเบฒเบกเบเบดเบเบเบฒเบเบเบญเบเบฅเบฐเบเบปเบเบชเบฒเบเบชเบปเปเบเปเบเบญเบฐเบเบธเบชเบฑเบเบเบฒ UDP เปเบกเปเบเบเบงเบฒเบกเบฎเบฑเบเบเบดเบเบเบญเบเบเบฑเบเบซเบกเบปเบเบเบญเบเปเบญเบฑเบเบเบฅเบดเปเบเบเบฑเบ.
เบเบฒเบเบเบงเบเบซเบฒเบเบงเบฒเบกเบเบดเบเบเบฒเบเปเบเปเบเปเบเบเบญเบ TCP เปเบกเปเบเบเบฑเบเบฅเบธเปเบเปเปเบเบเบเบฒเบเบชเปเบฒเบเบเบฑเปเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเบเปเบซเบเบเบชเบดเปเบเบชเบธเบ, เปเบเบฑเบเบฎเบฑเบเบชเบฒเบชเบฐเบเบฒเบเบฐเบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเปเบ, เบเบตเปเบเบญเบเบเปเบฒเบเบงเบ bytes เบเบตเปเบชเบปเปเบเปเบเปเบเปเบฅเบฐเบซเบปเบงเบเบญเบเปเบเบฑเบเปเบเบฑเบ, เปเบฅเบฐเปเบเปเบเปเบเบฎเบฑเบเปเบเบดเบเปเบเบเปเบเปเบเบปเบงเปเบฅเบเบเบฒเบเบฎเบฑเบเบฎเบนเป.
เบเบญเบเบเบฒเบเบเบฑเปเบ, เปเบเบทเปเบญเบเบฑเบเบเบธเบเบเบฒเบเบเบฐเบเบดเบเบฑเบ (i. e. เบชเบปเปเบเบซเบผเบฒเบเบเบงเปเบฒเบซเบเบถเปเบเบชเปเบงเบเปเบเบเบเปเปเปเบเปเบฎเบฑเบเบเบฒเบเบเบญเบกเบฎเบฑเบ), เปเบเปเบเบเบญเบ TCP เปเบเปเบญเบฑเบเบเบตเปเปเบญเบตเปเบเบงเปเบฒเบเปเบญเบเบขเปเบฝเบกเบชเบปเปเบ - เบเปเบฒเบเบงเบ bytes เบเบญเบเบเปเปเบกเบนเบเบเบตเปเบเบนเปเบชเบปเปเบเบเบญเบ segment เบเบฒเบเบงเปเบฒเบเบฐเปเบเปเบฎเบฑเบ.
เบชเปเบฒเบฅเบฑเบเบเปเปเบกเบนเบเปเบเบตเปเบกเปเบเบตเบกเบเปเบฝเบงเบเบฑเบ TCP protocol, เปเบเบดเปเบ
เบเบฒเบเบเปเบฒเบเปเบเบดเบ, เบกเบฑเบเปเบเบฑเบเบเบตเปเบเบฑเบเปเบเบเบงเปเบฒเปเบเบทเปเบญเบชเปเบฒเบเปเบเปเบเบเบญเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเปเปเบเบงเบฒเบกเบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเบซเบผเบฒเบเบเบงเปเบฒ UDP (เบเปเปเปเบเบเบตเปเปเบญเบตเปเบเบงเปเบฒ. UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป), เบกเบฑเบเบเปเบฒเปเบเบฑเบเบเปเบญเบเบเบฐเบเบดเบเบฑเบเบเบปเบเปเบเบเบฒเบเปเบญเบเบเปเปเบกเบนเบเบเบตเปเบเปเบฒเบเบเบทเบเบฑเบเบเบฑเบ TCP. เบเบท:
- เบเบฑเบเบเบถเบเบชเบฐเบเบฒเบเบฐเบเบฒเบเปเบเบทเปเบญเบกเบเปเป
- เปเบเปเปเบฅเบเบชเปเบงเบ
- เปเบเปเบเบธเบเบเบฒเบเบขเบทเบเบขเบฑเบเบเบดเปเบชเบ
- เปเบเปเบเบปเบเปเบ windowing เปเบเบเบเปเบฒเบเบเบฒเบเปเบเบทเปเบญเปเบเบตเปเบกเบเบฒเบเบชเบปเปเบเบเปเบฒเบเปเบเบฃเปเบเบเป
เบเบญเบเบเบฒเบเบเบฑเปเบ, เบเปเบฒเบเบเปเบญเบเบเบฒเบ:
- เบชเบฑเบเบเบฒเบเบเบฒเบเปเบฅเบตเปเบกเบเบปเปเบเบเบญเบเบเปเปเบเบงเบฒเบก, เปเบเบทเปเบญเบเบฑเบเบชเบฑเบเบเบฑเบเบเบฐเบเบฒเบเบญเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป
- เบชเบปเปเบเบชเบฑเบเบเบฒเบเบเบฒเบเบชเบดเปเบเบชเบธเบเบเบญเบเบเปเปเบเบงเบฒเบก, เปเบเบทเปเบญเบเปเบฒเบเบเบญเบเบเปเปเบเบงเบฒเบกเบเบตเปเปเบเปเบฎเบฑเบเปเบเบซเบฒเปเบญเบฑเบเบเบฅเบดเปเบเบเบฑเบเปเบเบดเบเบเปเปเบฒเปเบฅเบฐเบเปเบญเบเบเบฑเบเบเบฐเบเบฒเบเบญเบเปเบเบฃเปเบเบเป
- เบญเบฐโเบเบธโเบเบฒเบโเปเบซเปโเบญเบฐโเบเบธโเบเบฒเบโเบเบฒเบโเปเบเบทเปเบญเบกโเบเปเปโเบชเบฐโเปเบเบฒเบฐโเปเบเบทเปเบญโเบเบดเบโเบเบฒเบโเปเบเปโเบเบฒเบโเบเบปเบโเปเบโเบเบฒเบโเบขเบฑเปเบโเบขเบทเบโเบเบฒเบโเบเบฑเบโเบชเบปเปเบโเบเบตเปโเบเบฐโเปเบฎเบฑเบโเบงเบฝเบโเปเบเบฑเบ "เบเปโเบฅเบดโเบชเบธเบโ" UDP
เบชเปเบงเบเบซเบปเบง UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป
เบเบทเปเปเบงเปเบงเปเบฒ UDP datagram เปเบกเปเบ encapsulated เปเบ IP datagram. เปเบเบฑเบเปเบเบฑเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเปเบกเปเบ "เบซเปเป" เบขเปเบฒเบเปเบซเบกเบฒเบฐเบชเบปเบกเปเบเบปเปเบฒเปเบเปเบ UDP datagram.
เบเบฒเบเบซเบธเปเบกเบซเปเปเบซเบปเบง UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป:
เปเบเบเบชเปเบฒเบเบเบญเบเบซเบปเบง UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเปเบกเปเบเบเปเบญเบเบเปเบฒเบเบเปเบฒเบเบเบฒเบ:
- เบเบธเบ - package control flags
- MessageType - เบเบฐเปเบเบเบเปเปเบเบงเบฒเบกเบเบตเปเปเบเปเปเบเบเปเบญเบฑเบเบเบฅเบดเปเบเบเบฑเบเปเบเบดเบเบเบฐเปเบชเปเบเบทเปเบญเบชเบฐเปเบฑเบเบฎเบฑเบเบเปเปเบเบงเบฒเบกเบชเบฐเปเบเบฒเบฐ
- TransmissionId - เบเปเบฒโเบเบงเบโเบเบญเบโเบเบฒเบโเบชเบปเปเบโ, เบฎเปเบงเบกโเบเบฑเบโเบเบตเปโเบขเบนเปโเปเบฅเบฐโเบเบญเบโเบเบญเบโเบเบนเปโเบฎเบฑเบโ, เปเบเบฑเบโเปเบญโเบเบฐโเบฅเบฑเบโเบฅเบฐโเบเบธโเบเบฒเบโเปเบเบทเปเบญเบกโเบเปเปโ.
- PacketNumber - เปเบฅเบเปเบเบฑเบเปเบเบฑเบ
- เบเบปเบงเปเบฅเบทเบญเบ - เบเบปเบงเปเบฅเบทเบญเบเปเบเบฃเปเบเบเปเปเบเบตเปเบกเปเบเบตเบก. เปเบเบเปเบฅเบฐเบเบตเบเบญเบเบเบธเบเบเปเบฒเบญเบดเบ, เบกเบฑเบเบเบทเบเบเปเบฒเปเบเปเปเบเบทเปเบญเบเบตเปเบเบญเบเบเบฐเบซเบเบฒเบเบเบญเบเบเปเปเบเบงเบฒเบก
เบเบธเบโเบเบฑเปเบโเบเปเปโเปเบโเบเบตเปโ:
- FirstPacket - เบเบธเบเบเปเบฒเบญเบดเบเบเบญเบเบเปเปเบเบงเบฒเบก
- NoAsk - เบเปเปเบเบงเบฒเบกเบเปเปเบฎเบฝเบเบฎเปเบญเบเปเบซเปเบกเบตเบเบปเบเปเบเบเบฒเบเบฎเบฑเบเบฎเบนเปเปเบเบทเปเบญเปเบเบตเบเปเบเปเบเบฒเบ
- LastPacket - เบเบธเบเบชเบธเบเบเปเบฒเบเบเบญเบเบเปเปเบเบงเบฒเบก
- RequestForPacket - เบเบธเบโเบเบฒเบโเบขเบฑเปเบโเบขเบทเบโเบซเบผเบทโเบเบฒเบโเบฎเปเบญเบโเบเปโเบชเปเบฒโเบฅเบฑเบโเบเบฒเบโเบชเบนเบโเปเบชเบโเบเบญเบโ
เบซเบผเบฑเบเบเบฒเบเบเบปเปเบงเปเบเบเบญเบเบญเบฐเบเบธเบชเบฑเบเบเบฒ
เปเบเบทเปเบญเบเบเบฒเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเปเบกเปเบเบชเบธเบกเปเบชเปเบเบฒเบเบฎเบฑเบเบเบฐเบเบฑเบเบเบฒเบเบชเบปเปเบเบเปเปเบเบงเบฒเบกเบฅเบฐเบซเบงเปเบฒเบเบชเบญเบ nodes, เบกเบฑเบเบเปเบญเบเบชเบฒเบกเบฒเบเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเบเบญเบตเบเบเปเบฒเบเบซเบเบถเปเบ. เปเบเบทเปเบญเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป, เบเบนเปเบชเบปเปเบเบเบฐเบชเบปเปเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบกเบตเบเบธเบ FirstPacket, เบเปเบฒเบเบญเบเบเบตเปเบเบฐเบซเบกเบฒเบเบเบงเบฒเบกเบงเปเบฒเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเปเบเบทเบเบชเปเบฒเบเบเบฑเปเบเบเบถเปเบ. เปเบเบฑเบเปเบเบฑเบเบฎเบฑเบเบเบฒเบเบเบญเบเบฎเบฑเบเบเบฑเบเปเบปเบ, เบซเบผเบทเปเบงเบปเปเบฒเบญเบตเบเบขเปเบฒเบเปเบถเปเบ, เปเบเบฑเบเปเบเบฑเบเบฎเบฑเบเบเบฒเบเบฎเบฑเบเบฎเบนเป, เบเบณเบเบปเบเบเปเบฒเบเบญเบเบเปเบญเบ PacketNumber เบชเบฐเปเปเบตเปเบเบฑเบเปเบถเปเบเบซเบผเบฒเบเบเบงเปเบฒเบเปเบฒ PacketNumber เบเบตเปเปเบซเบเปเบเบตเปเบชเบธเบเบเบญเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเปเบเปเบฎเบฑเบเบชเบณเปเบฅเบฑเบ. เบเปเบญเบเบเบปเบงเปเบฅเบทเบญเบเบชเปเบฒเบฅเบฑเบเปเบเบฑเบเปเบเบฑเบเบเปเบฒเบญเบดเบเบเบตเปเบชเบปเปเบเปเบกเปเบเบเบฐเบซเบเบฒเบเบเบญเบเบเปเปเบเบงเบฒเบก.
เบเบปเบเปเบเบเบตเปเบเปเบฒเบเบเบทเบเบฑเบเปเบกเปเบเปเบเปเปเบเบทเปเบญเบขเบธเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป. เบเบธเบ LastPacket เบเบทเบเบเบฑเปเบเบขเบนเปเปเบเปเบเบฑเบเปเบเบฑเบเบชเบธเบเบเปเบฒเบเบเบญเบเบเปเปเบเบงเบฒเบก. เปเบเบเบญเบเบเบญเบเบฎเบฑเบ, เบเบปเบงเปเบฅเบเบเบญเบเบเบญเบเบชเบธเบเบเปเบฒเบ + 1 เปเบกเปเบเบเบตเปเปเบซเปเปเบซเบฑเบ, เปเบเบดเปเบเบชเปเบฒเบฅเบฑเบเบเปเบฒเบเบเบตเปเปเบเปเบฎเบฑเบเบซเบกเบฒเบเบเบงเบฒเบกเบงเปเบฒเบเบฒเบเบเบฑเบเบชเบปเปเบเบเปเปเบเบงเบฒเบกเบชเบปเบเบเบปเบเบชเปเบฒเปเบฅเบฑเบ.
เปเบเบโเบงเบฒเบโเบเบฒเบโเบชเปเบฒเบโเบเบฑเปเบโเปเบฅเบฐโเบเบฒเบโเบชเบดเปเบโเบชเบธเบโเบเบฒเบโเปเบเบทเปเบญเบกโเบเปเปโ:
เปเบกเบทเปเบญเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเปเบเบทเบเบชเปเบฒเบเบเบฑเปเบเบเบถเปเบ, เบเบฒเบเปเบญเบเบเปเปเบกเบนเบเปเบฅเบตเปเบกเบเบปเปเบ. เบเปเปโเบกเบนเบโเปเบกเปเบโเปเบเปโเบฎเบฑเบโเบเบฒเบโเบชเบปเปเบโเบญเบญเบโเปเบโเบเบฑเบโเบเบญเบโเบเบญเบโ. เปเบเปเบฅเบฐเบเบฅเบฑเบญเบ, เบเบปเบเปเบงเบฑเปเบเบญเบฑเบเบชเบธเบเบเปเบฒเบ, เบกเบตเบเปเบฒเบเบงเบเปเบเบฑเบเปเบเบฑเบเบเบปเบเบเบตเป. เบกเบฑเบเปเบเบปเปเบฒเบเบฑเบเบเบฐเบซเบเบฒเบเบเปเบญเบเบขเปเบฝเบกเบฎเบฑเบ / เบชเบปเปเบ. เบเปเปเบกเบนเบเบเบฅเบฑเบญเบเบชเบธเบเบเปเบฒเบเบญเบฒเบเบกเบตเปเบเบฑเบเปเบเบฑเบเปเปเบญเบเบฅเบปเบ. เบซเบผเบฑเบเบเบฒเบเบเบฒเบเบชเบปเปเบเปเบเปเบฅเบฐเบเบฑเบ, เบเปเบฒเบเบชเบปเปเบเบฅเปเบเปเบฒเบเบฒเบเบขเบทเบเบขเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบซเบผเบทเบเบฒเบเบฎเปเบญเบเบเปเปเบซเปเบชเบปเปเบเบเบทเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบนเบเปเบชเบเปเบ, เปเบฎเบฑเบเปเบซเปเบเปเบญเบเบขเปเบฝเบกเบฎเบฑเบ / เบชเบปเปเบเปเบเบตเบเปเบเบทเปเบญเบฎเบฑเบเบเปเบฒเบเบญเบ. เบซเบผเบฑเบโเบเบฒเบโเปเบเปโเบฎเบฑเบโเบเบฒเบโเบขเบทเบโเบขเบฑเบโเบเบฒเบโเบเบฑเบโเบชเบปเปเบ block, เบเบฒเบโเบฎเบฑเบ / เบชเบปเปเบโเบเปเบญเบโเบขเปเบฝเบกโเบเปเบฝเบโเปเบฅเบฐโเบเบฒเบโเบเปเปโเปเบโเบเบญเบโเบเปเปโเบกเบนเบโเปเบเปโเบเบทเบโเบชเบปเปเบโเปเบโ.
เบเปเบฒเบเบเบตเปเปเบเปเบฎเบฑเบเปเบกเปเบเปเบเปเบฎเบฑเบเบเบญเบ. เปเบเปเบฅเบฐเปเบเบฑเบเปเบเบฑเบเบเบทเบเบเบงเบเบชเบญเบเปเบเบทเปเบญเปเบเบดเปเบเบงเปเบฒเบกเบฑเบเบเบปเบเบขเบนเปเปเบเบเปเบญเบเบขเปเบฝเบกเบชเบปเปเบ. เบเบฒเบเบซเบธเปเบกเบซเปเปเปเบฅเบฐเบเปเปเบฒเบเบฑเบเบเบตเปเบเปเปเบเบปเบเบขเบนเปเปเบเบเปเบญเบเบขเปเบฝเบกเปเบกเปเบเบเบฒเบเบเบฑเปเบเบเบญเบเบญเบญเบ. เปเบเบทเปเบญเบเบเบฒเบเบงเปเบฒ เบเปเบฒเบเบฐเบซเบเบฒเบเบเบญเบเบเปเบญเบเบขเปเบฝเบกเบเบทเบเปเบเปเปเบเปเบฅเบฐเบเบทเบเบฑเบเบชเปเบฒเบฅเบฑเบเบเบนเปเบฎเบฑเบเปเบฅเบฐเบเบนเปเบชเบปเปเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบ, เปเบเบเปเบฅเบฐเบเบตเบเบญเบเบเบฑเบเบเบญเบเปเบเบฑเบเปเบเบฑเบเบเบทเบเบชเบปเปเบเปเบเบเบเปเปเบกเบตเบเบฒเบเบชเบนเบเปเบชเบ, เบเปเบญเบเบขเปเบฝเบกเบเบฐเบเบทเบเบเปเบฝเบเปเบเปเบเบทเปเบญเบฎเบฑเบเปเบเบฑเบเปเบเบฑเบเบเบญเบเบเปเปเบกเบนเบเบเปเปเปเบเปเบฅเบฐเบเบฒเบเบขเบทเบเบขเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเปเบกเปเบ. เบชเบปเปเบ. เบเปเบฒเบเปเบญเบเบขเปเบฝเบกเบเปเปเบเบทเปเบกเบเปเปเบกเบนเบเบเบฒเบเปเบเปเบฅเบเบฐเปเบงเบฅเบฒเบเบตเปเบเปเบฒเบเบปเบเปเบงเปเปเบเบเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบฒเบเบเบงเบเบชเบญเบเบเบฐเบเบทเบเปเบฅเบตเปเบกเบเบปเปเบเบเบตเปเปเบเบฑเบเปเบเบฑเบเบเบตเปเบเบฑเบเบเปเปเปเบเปเบชเบปเปเบเปเบฅเบฐเบเปเบฒเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบเบเบฐเบเบทเบเบชเบปเปเบ.
เปเบเบเบงเบฒเบเบเบฒเบเบชเบปเปเบเบเปเป:
เปเบปเบเปเบงเบฅเบฒ เปเบฅเบฐเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบเบฃเปเบเบเป
เบกเบตเบซเบผเบฒเบเปเบซเบเบเบปเบเบงเปเบฒเปเบเบฑเบเบซเบเบฑเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเปเปเบชเบฒเบกเบฒเบเบเบทเบเบชเปเบฒเบเบเบฑเปเบเบเบถเปเบ. เบเบปเบงเบขเปเบฒเบ, เบเปเบฒเบเปเบฒเบเบฎเบฑเบเปเบกเปเบเบญเบญเบเปเบฅเบเป. เปเบเบเปเบฅเบฐเบเบตเบเบตเป, เปเบกเบทเปเบญเบเบฐเบเบฒเบเบฒเบกเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป, เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฐเบเบทเบเบเบดเบเปเบเบเบซเบกเบปเบเปเบงเบฅเบฒ. เบเบฒเบเบเบฐเบเบดเบเบฑเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเปเบเปเบชเบญเบเบเบปเบงเบเบฑเบเปเบงเบฅเบฒเปเบเบทเปเบญเบเปเบฒเบเบปเบเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒ. เบเปเบฒเบญเบดเบ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบ, เบเบทเบเบเปเบฒเปเบเปเปเบเบทเปเบญเบฅเปเบเปเบฒเบเบฒเบเบเบญเบเบชเบฐเบซเบเบญเบเบเบฒเบเปเบเบปเปเบฒเบเบฒเบเบซเปเบฒเบเปเบเบชเบญเบเบซเบผเบตเบ. เบเปเบฒเบกเบฑเบเปเบเปเบซเบกเปเบขเบนเปเบเปเบฒเบเบเบนเปเบชเบปเปเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบปเปเบเบชเบธเบเบเปเบฒเบเปเบกเปเบ resent. เบเปเบฒเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบปเบเบญเบฒเบเบธเบขเบนเปเบเบนเปเบฎเบฑเบ, เบเบฒเบเบเบงเบเบชเบญเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบนเบเบซเบฒเบเบเบฐเบเบทเบเบเบฐเบเบดเบเบฑเบ เปเบฅเบฐ เบเบฒเบเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบเบเบฐเบเบทเบเบชเบปเปเบ.
เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเบเบตเบชเบญเบเปเบกเปเบเบเปเบฒเปเบเบฑเบเปเบเบทเปเบญเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบเปเบฅเบฐเบเบตเบเบตเปเบเบฒเบเบเบฒเบเบชเบทเปเบชเบฒเบเบฅเบฐเบซเบงเปเบฒเบเปเบซเบเบ. เบชเปเบฒเบฅเบฑเบเบเปเบฒเบเบเบนเปเบชเบปเปเบ, เบกเบฑเบเปเบฅเบตเปเบกเบเบปเปเบเบเบฑเบเบเบตเบซเบผเบฑเบเบเบฒเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบซเบกเบปเบเบญเบฒเบเบธ, เปเบฅเบฐเบฅเปเบเปเบฒเบเบฒเบเบเบญเบเบชเบฐเบซเบเบญเบเบเบฒเบ node เบซเปเบฒเบเปเบเบชเบญเบเบซเบผเบตเบ. เบเปเบฒเบเปเปเบกเบตเบเบฒเบเบเบญเบเบชเบฐเบซเบเบญเบเบเบฒเบเปเบเปเบฅเบเบฐเปเบงเบฅเบฒเบเบตเปเบเปเบฒเบเบปเบ, เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบทเบเบเบดเบเปเบฅเบฐเบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบทเบเบเปเบญเบเบญเบญเบเบกเบฒ. เบชเปเบฒเบฅเบฑเบเบเปเบฒเบเบเบฒเบเบฎเบฑเบ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบเปเบเบดเบเบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบกเปเบเปเบฅเบตเปเบกเบเบปเปเบเบซเบผเบฑเบเบเบฒเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบซเบกเบปเบเบญเบฒเบเบธเบชเบญเบเบเบฑเปเบ. เบเบตเปเปเบกเปเบเบชเบดเปเบเบเปเบฒเปเบเบฑเบเปเบเบทเปเบญเบฎเบฑเบเบเบฐเบเบฑเบเบเบฒเบเบชเบนเบเปเบชเบเบเบธเบเบเบฒเบเบขเบทเบเบขเบฑเบ. เปเบกเบทเปเบญเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเบซเบกเบปเบเบญเบฒเบเบธ, เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเปเปเบเบทเบเบเบดเบเปเบฅเบฐเบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบทเบเบเปเบญเบเบญเบญเบเบกเบฒ.
เปเบเบเบงเบฒเบเบชเบฐเบเบฒเบเบฐเบชเบฒเบเบชเบปเปเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป
เบซเบผเบฑเบเบเบฒเบเบเบญเบเปเบเปเบเบเบญเบเบเบทเบเบเบฐเบเบดเบเบฑเบเบขเบนเปเปเบเปเบเบทเปเบญเบเบเบญเบเบฅเบฑเบเบเบตเปเบเปเบฒเบเบฑเบ, เปเบเปเบฅเบฐเบฅเบฑเบเบเบตเปเบฎเบฑเบเบเบดเบเบเบญเบเบเปเปเปเบซเบเบเบปเบเบเบตเปเปเบเปเบเบญเบเบเบญเบเบเบฒเบเบเบธเบเปเบเปเบเปเบเบฑเบเปเบเบฑเบ.
เปเบเบเบงเบฒเบเบฅเบฑเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป:
เบเบดเบ - เบเปเปเปเบกเปเบเบฅเบฑเบเปเบเปเป, เบกเบฑเบเปเบเบฑเบเบเบธเบเปเบฅเบตเปเบกเบเบปเปเบเปเบฅเบฐเบเบธเบเบชเบดเปเบเบชเบธเบเบเบญเบ automaton. เบชเปเบฒเบฅเบฑเบเบฅเบฑเบ เบเบดเบ เบเบฑเบเบเบงเบเบเบธเบกเบฅเบฐเบเบปเบเบชเบฒเบเบชเบปเปเบเปเบกเปเบเปเบเปเบฎเบฑเบ, เปเบเบดเปเบ, เบเบฒเบเบเบฐเบเบดเบเบฑเบเปเบเบทเปเบญเบเปเบกเปเบเปเบฒเบ UDP asynchronous, เบชเบปเปเบเบเปเปเปเบเบฑเบเปเบเบฑเบเปเบเบซเบฒเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบตเปเปเบซเบกเบฒเบฐเบชเบปเบกเปเบฅเบฐเปเบฅเบตเปเบกเบเบปเปเบเบเบฒเบเบเบธเบเปเบเปเบเบเบญเบเบฅเบฑเบ.
FirstPacketSending โ เบชเบฐเบเบฒเบเบฐเปเบเบทเปเบญเบเบเบปเปเบเบเบตเปเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเบญเบญเบเปเบกเปเบเปเบกเบทเปเบญเบเปเปเบเบงเบฒเบกเบเบทเบเบชเบปเปเบ.
เปเบเบชเบฐเบเบฒเบเบฐเบเบตเป, เบเบธเบเบเปเบฒเบญเบดเบเบชเปเบฒเบฅเบฑเบเบเปเปเบเบงเบฒเบกเบเบปเบเบเบฐเบเบดเปเบกเปเบเบเบทเบเบชเบปเปเบเปเบ. เบชเปเบฒเบฅเบฑเบเบเปเปเบเบงเบฒเบกเบเบตเปเบเปเปเบกเบตเบเบฒเบเบขเบทเบเบขเบฑเบเบเบฒเบเบชเบปเปเบ, เบเบตเปเปเบกเปเบเบชเบฐเบเบฒเบเบฐเบเบฝเบงเบเบตเปเบเปเปเบเบงเบฒเบกเบเบฑเบเบซเบกเบปเบเบเบทเบเบชเบปเปเบเปเบ.
เบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ โ เบเบทเปเบโเบเบฒเบโเบชเบฐโเบเบฒโเบเบฐโเบเบฒเบโเบชเปเบฒโเบฅเบฑเบโเบเบฒเบโเบชเบปเปเบโเบเบญเบโเบเบญเบโเบเปเปโเบเบงเบฒเบกโ.
เบเบฒเบเบซเบฑเบเบเปเบฝเบเปเบเบเบฒเบเบฅเบฑเบ FirstPacketSending เบเบฐเบเบดเบเบฑเบเบซเบผเบฑเบเบเบฒเบเบเบธเบเบเปเบฒเบญเบดเบเบเบญเบเบเปเปเบเบงเบฒเบกเปเบเปเบเบทเบเบชเบปเปเบ. เบกเบฑเบเปเบกเปเบเบขเบนเปเปเบเบชเบฐเบเบฒเบเบฐเบเบตเปเบงเปเบฒเบเบฒเบเบฎเบฑเบเบฎเบนเปเปเบฅเบฐเบเบฒเบเบฎเปเบญเบเบเปเบเบฑเบเบซเบกเบปเบเบชเปเบฒเบฅเบฑเบ retransmissions เบกเบฒ. เบเบฒเบเบญเบญเบเบเบฒเบเบกเบฑเบเปเบเบฑเบเปเบเปเบเปเปเบเบชเบญเบเบเปเบฅเบฐเบเบต - เปเบเบเปเบฅเบฐเบเบตเบเบญเบเบเบฒเบเบชเบปเปเบเบเปเปเบเบงเบฒเบกเบชเบปเบเบเบปเบเบชเปเบฒเปเบฅเบฑเบเบซเบผเบทเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒ.
FirstPacket เปเบเปเบฎเบฑเบ - เบชเบฐเบเบฒเบเบฐเปเบเบทเปเบญเบเบเบปเปเบเบชเบณเบฅเบฑเบเบเบนเปเบฎเบฑเบเบเปเปเบเบงเบฒเบก.
เบกเบฑเบเบเบงเบเบชเบญเบเบเบงเบฒเบกเบเบทเบเบเปเบญเบเบเบญเบเบเบฒเบเปเบฅเบตเปเบกเบเบปเปเบเบเบญเบเบเบฒเบเบชเบปเปเบเบเปเป, เบชเปเบฒเบเปเบเบเบชเปเบฒเบเบเบตเปเบเปเบฒเปเบเบฑเบ, เปเบฅเบฐเบชเบปเปเบเบเบฒเบเบฎเบฑเบเบฎเบนเปเบเบฒเบเบฎเบฑเบเบเบญเบเบเบธเบเบเปเบฒเบญเบดเบ.
เบชเปเบฒเบฅเบฑเบเบเปเปเบเบงเบฒเบกเบเบตเปเบเบฐเบเบญเบเบเปเบงเบเบเบญเบเบเบฝเบงเปเบฅเบฐเบเบทเบเบชเบปเปเบเปเบเบเบเปเปเบกเบตเบเบฒเบเบเปเบฒเปเบเปเบซเบผเบฑเบเบเบฒเบเบชเบฐเปเบเบเบเบฒเบเบเบฑเบเบชเบปเปเบ, เบเบตเปเปเบกเปเบเบฅเบฑเบเบเบฝเบง. เบซเบผเบฑเบเบเบฒเบเบเบฒเบเบเบฐเบกเบงเบเบเบปเบเบเปเปเบเบงเบฒเบกเบเบฑเปเบเบเปเบฒเบง, เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบทเบเบเบดเบ.
เบเบฒเบเบเบดเบเบเบฑเปเบ - เบฅเบฑเบโเบเบทเปเบโเบเบฒเบโเบชเปเบฒโเบฅเบฑเบโเบเบฒเบโเปเบเปโเบฎเบฑเบโเบเบญเบโเบเปเปโเบเบงเบฒเบกโ.
เบกเบฑเบเบเบฝเบเปเบเบฑเบเปเบเบฑเบเปเบชเปเบเปเบญเบเปเบเบฑเบเบกเปเบฝเบเบเบปเปเบงเบเบฒเบง, เบเบงเบเปเบเบดเปเบเบเบฒเบเบชเบนเบเปเบชเบเปเบเบฑเบเปเบเบฑเบ, เบชเบปเปเบเบเบฒเบเบฎเบฑเบเบฎเบนเปเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบญเบเปเบเบฑเบเปเบเบฑเบเปเบฅเบฐเบเปเปเบเบงเบฒเบกเบเบฑเบเบซเบกเบปเบ, เปเบฅเบฐเบชเบปเปเบเบเปเบฒเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบเบเบญเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบนเบเปเบชเบ. เปเบเบเปเบฅเบฐเบเบตเบเบตเปเปเบเปเบฎเบฑเบเบเบปเบเบชเปเบฒเปเบฅเบฑเบเบเบญเบเบเปเปเบเบงเบฒเบกเบเบฑเบเบซเบกเบปเบ, เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบปเปเบฒเปเบเปเบเบฅเบฑเบ เบชเปเบฒเปเบฅเบฑเบเบเปเบฒเบเปเปเบเบฑเปเบเบเบฑเปเบ, เบเบฒเบเปเบปเบเปเบงเบฅเบฒเบญเบญเบ.
เบชเปเบฒเปเบฅเบฑเบ - เบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบเปเบฅเบฐเบเบตเบเบตเปเปเบเปเบฎเบฑเบเบเปเปเบเบงเบฒเบกเบเบฑเบเปเบปเบเบชเบณเปเบฅเบฑเบ.
เบฅเบฑเบเบเบตเปเปเบกเปเบเบกเบตเบเบงเบฒเบกเบเปเบฒเปเบเบฑเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบธเบกเบเบธเบกเบเบญเบเบเปเปเบเบงเบฒเบกเปเบฅเบฐเบชเปเบฒเบฅเบฑเบเบเปเบฅเบฐเบเบตเปเบเปเบงเบฅเบฒเบเบตเปเบเบฒเบเบขเบฑเปเบเบขเบทเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบญเบเบเปเปเบเบงเบฒเบกเปเบเปเบชเบนเบเปเบชเบเปเบเปเบเบเบฒเบเบเบฑเบเบเบนเปเบชเบปเปเบ. เบชเบฐเบเบฒเบเบฐเบเบตเปเบเบทเบเบเบดเบเปเบงเปเปเบเบเบเบฒเบเปเบปเบเปเบงเบฅเบฒ, เปเบเปเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบทเบเบเบทเบงเปเบฒเบเบดเบเบขเปเบฒเบเบชเบณเปเบฅเบฑเบเบเบปเบ.
เปเบฅเบดเบเปเบเบปเปเบฒเปเบเปเบเบฅเบฐเบซเบฑเบ. เบซเบเปเบงเบโเบเบงเบโเบเบธเบกโเบชเบฒเบโเบชเบปเปเบโ
เบซเบเบถเปเบเปเบเบญเบปเบเบเบฐเบเบญเบเบเบตเปเบชเปเบฒเบเบฑเบเบเบญเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเปเบกเปเบเบเบฑเบเบเบงเบเบเบธเบกเบฅเบฐเบเบปเบเบชเบฒเบเบชเบปเปเบ. เบงเบฝเบเบเบฒเบเบเบญเบเบเบฑเบเบเบตเปเปเบกเปเบเปเบเบทเปเบญเปเบเบฑเบเบฎเบฑเบเบชเบฒเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบเบฐเบเบธเบเบฑเบเปเบฅเบฐเบญเบปเบเบเบฐเบเบญเบเบเปเบงเบ, เปเบเบเบขเบฒเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเปเบเบปเปเบฒเบกเบฒเปเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบตเปเบชเบญเบเบเปเบญเบเบเบฑเบ, เบชเบฐเบซเบเบญเบเบเบฒเบเปเบเปเบเบญเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบปเปเบเปเบเบฑเบเปเบเบฑเบเปเบเบซเบฒเบเบฒเบเปเบเบทเปเบญเบกเบเปเป, เปเบฅเบฐเบเบฐเบเบดเบเบฑเบ API เบเบญเบเปเบเปเบเบเบญเบ. เบเบฅเบฑเบญเบเบเบงเบเบเบธเบกเบฅเบฐเบเบปเบเบชเบฒเบเบชเบปเปเบเปเบเปเบฎเบฑเบเปเบเบฑเบเปเบเบฑเบเบเบฒเบเบเบฑเปเบ UDP เปเบฅเบฐเบชเบปเปเบเบเปเปเปเบเบซเบฒเปเบเบทเปเบญเบเบเบญเบเบฅเบฑเบเปเบเบทเปเบญเบเบฐเบกเบงเบเบเบปเบ. เปเบเบทเปเบญเปเบซเปเปเบเปเบฎเบฑเบเปเบเบฑเบเปเบเบฑเบ, เบกเบฑเบเบเบฐเบเบดเบเบฑเบเปเบเบทเปเบญเบเปเบกเปเบเปเบฒเบ UDP เปเบเบ asynchronous.
เบชเบฐเบกเบฒเบเบดเบเบเบฒเบเบเบปเบเบเบญเบเบซเปเบญเบเบฎเบฝเบ ReliableUdpConnectionControlBlock:
internal class ReliableUdpConnectionControlBlock : IDisposable
{
// ะผะฐััะธะฒ ะฑะฐะนั ะดะปั ัะบะฐะทะฐะฝะฝะพะณะพ ะบะปััะฐ. ะัะฟะพะปัะทัะตััั ะดะปั ัะฑะพัะบะธ ะฒั
ะพะดััะธั
ัะพะพะฑัะตะฝะธะน
public ConcurrentDictionary<Tuple<EndPoint, Int32>, byte[]> IncomingStreams { get; private set;}
// ะผะฐััะธะฒ ะฑะฐะนั ะดะปั ัะบะฐะทะฐะฝะฝะพะณะพ ะบะปััะฐ. ะัะฟะพะปัะทัะตััั ะดะปั ะพัะฟัะฐะฒะบะธ ะธัั
ะพะดััะธั
ัะพะพะฑัะตะฝะธะน.
public ConcurrentDictionary<Tuple<EndPoint, Int32>, byte[]> OutcomingStreams { get; private set; }
// connection record ะดะปั ัะบะฐะทะฐะฝะฝะพะณะพ ะบะปััะฐ.
private readonly ConcurrentDictionary<Tuple<EndPoint, Int32>, ReliableUdpConnectionRecord> m_listOfHandlers;
// ัะฟะธัะพะบ ะฟะพะดะฟะธััะธะบะพะฒ ะฝะฐ ัะพะพะฑัะตะฝะธั.
private readonly List<ReliableUdpSubscribeObject> m_subscribers;
// ะปะพะบะฐะปัะฝัะน ัะพะบะตั
private Socket m_socketIn;
// ะฟะพัั ะดะปั ะฒั
ะพะดััะธั
ัะพะพะฑัะตะฝะธะน
private int m_port;
// ะปะพะบะฐะปัะฝัะน IP ะฐะดัะตั
private IPAddress m_ipAddress;
// ะปะพะบะฐะปัะฝะฐั ะบะพะฝะตัะฝะฐั ัะพัะบะฐ
public IPEndPoint LocalEndpoint { get; private set; }
// ะบะพะปะปะตะบัะธั ะฟัะตะดะฒะฐัะธัะตะปัะฝะพ ะธะฝะธัะธะฐะปะธะทะธัะพะฒะฐะฝะฝัั
// ัะพััะพัะฝะธะน ะบะพะฝะตัะฝะพะณะพ ะฐะฒัะพะผะฐัะฐ
public StatesCollection States { get; private set; }
// ะณะตะฝะตัะฐัะพั ัะปััะฐะนะฝัั
ัะธัะตะป. ะัะฟะพะปัะทัะตััั ะดะปั ัะพะทะดะฐะฝะธั TransmissionId
private readonly RNGCryptoServiceProvider m_randomCrypto;
//...
}
เบเบฒเบเบเบฐเบเบดเบเบฑเบเบเบญเบเปเบเบทเปเบญเบเปเบกเปเบเปเบฒเบ UDP asynchronous:
private void Receive()
{
EndPoint connectedClient = new IPEndPoint(IPAddress.Any, 0);
// ัะพะทะดะฐะตะผ ะฝะพะฒัะน ะฑััะตั, ะดะปั ะบะฐะถะดะพะณะพ socket.BeginReceiveFrom
byte[] buffer = new byte[DefaultMaxPacketSize + ReliableUdpHeader.Length];
// ะฟะตัะตะดะฐะตะผ ะฑััะตั ะฒ ะบะฐัะตััะฒะต ะฟะฐัะฐะผะตััะฐ ะดะปั ะฐัะธะฝั
ัะพะฝะฝะพะณะพ ะผะตัะพะดะฐ
this.m_socketIn.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref connectedClient, EndReceive, buffer);
}
private void EndReceive(IAsyncResult ar)
{
EndPoint connectedClient = new IPEndPoint(IPAddress.Any, 0);
int bytesRead = this.m_socketIn.EndReceiveFrom(ar, ref connectedClient);
//ะฟะฐะบะตั ะฟะพะปััะตะฝ, ะณะพัะพะฒั ะฟัะธะฝะธะผะฐัั ัะปะตะดัััะธะน
Receive();
// ั.ะบ. ะฟัะพััะตะนัะธะน ัะฟะพัะพะฑ ัะตัะธัั ะฒะพะฟัะพั ั ะฑััะตัะพะผ - ะฟะพะปััะธัั ัััะปะบั ะฝะฐ ะฝะตะณะพ
// ะธะท IAsyncResult.AsyncState
byte[] bytes = ((byte[]) ar.AsyncState).Slice(0, bytesRead);
// ะฟะพะปััะฐะตะผ ะทะฐะณะพะปะพะฒะพะบ ะฟะฐะบะตัะฐ
ReliableUdpHeader header;
if (!ReliableUdpStateTools.ReadReliableUdpHeader(bytes, out header))
{
// ะฟัะธัะตะป ะฝะตะบะพััะตะบัะฝัะน ะฟะฐะบะตั - ะพัะฑัะฐััะฒะฐะตะผ ะตะณะพ
return;
}
// ะบะพะฝััััะธััะตะผ ะบะปัั ะดะปั ะพะฟัะตะดะตะปะตะฝะธั connection recordโะฐ ะดะปั ะฟะฐะบะตัะฐ
Tuple<EndPoint, Int32> key = new Tuple<EndPoint, Int32>(connectedClient, header.TransmissionId);
// ะฟะพะปััะฐะตะผ ัััะตััะฒััััั connection record ะธะปะธ ัะพะทะดะฐะตะผ ะฝะพะฒัั
ReliableUdpConnectionRecord record = m_listOfHandlers.GetOrAdd(key, new ReliableUdpConnectionRecord(key, this, header.ReliableUdpMessageType));
// ะทะฐะฟััะบะฐะตะผ ะฟะฐะบะตั ะฒ ะพะฑัะฐะฑะพัะบั ะฒ ะบะพะฝะตัะฝัะน ะฐะฒัะพะผะฐั
record.State.ReceivePacket(record, header, bytes);
}
เบชเปเบฒเบฅเบฑเบเปเบเปเบฅเบฐเบเบฒเบเปเบญเบเบเปเปเบเบงเบฒเบก, เปเบเบเบชเปเบฒเบเบเบทเบเบชเปเบฒเบเบเบทเปเบเบเบตเปเบเบฐเบเบญเบเบเปเบงเบเบเปเปเบกเบนเบเบเปเบฝเบงเบเบฑเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป. เปเบเบเบชเปเบฒเบเบเบฑเปเบเบเปเบฒเบงเปเบญเบตเปเบเบงเปเบฒ เบเบฑเบเบเบถเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป.
เบชเบฐเบกเบฒเบเบดเบเบเบฒเบเบเบปเบเบเบญเบเบซเปเบญเบเบฎเบฝเบ ReliableUdpConnectionRecord:
internal class ReliableUdpConnectionRecord : IDisposable
{
// ะผะฐััะธะฒ ะฑะฐะนั ั ัะพะพะฑัะตะฝะธะตะผ
public byte[] IncomingStream { get; set; }
// ัััะปะบะฐ ะฝะฐ ัะพััะพัะฝะธะต ะบะพะฝะตัะฝะพะณะพ ะฐะฒัะพะผะฐัะฐ
public ReliableUdpState State { get; set; }
// ะฟะฐัะฐ, ะพะดะฝะพะทะฝะฐัะฝะพ ะพะฟัะตะดะตะปัััะฐั connection record
// ะฒ ะฑะปะพะบะต ัะฟัะฐะฒะปะตะฝะธั ะฟะตัะตะดะฐัะตะน
public Tuple<EndPoint, Int32> Key { get; private set;}
// ะฝะธะถะฝัั ะณัะฐะฝะธัะฐ ะฟัะธะตะผะฝะพะณะพ ะพะบะฝะฐ
public int WindowLowerBound;
// ัะฐะทะผะตั ะพะบะฝะฐ ะฟะตัะตะดะฐัะธ
public readonly int WindowSize;
// ะฝะพะผะตั ะฟะฐะบะตัะฐ ะดะปั ะพัะฟัะฐะฒะบะธ
public int SndNext;
// ะบะพะปะธัะตััะฒะพ ะฟะฐะบะตัะพะฒ ะดะปั ะพัะฟัะฐะฒะบะธ
public int NumberOfPackets;
// ะฝะพะผะตั ะฟะตัะตะดะฐัะธ (ะธะผะตะฝะฝะพ ะพะฝ ะธ ะตััั ะฒัะพัะฐั ัะฐััั Tuple)
// ะดะปั ะบะฐะถะดะพะณะพ ัะพะพะฑัะตะฝะธั ัะฒะพะน
public readonly Int32 TransmissionId;
// ัะดะฐะปะตะฝะฝัะน IP endpoint โ ัะพะฑััะฒะตะฝะฝะพ ะฟะพะปััะฐัะตะปั ัะพะพะฑัะตะฝะธั
public readonly IPEndPoint RemoteClient;
// ัะฐะทะผะตั ะฟะฐะบะตัะฐ, ะฒะพ ะธะทะฑะตะถะฐะฝะธะต ััะฐะณะผะตะฝัะฐัะธะธ ะฝะฐ IP ััะพะฒะฝะต
// ะฝะต ะดะพะปะถะตะฝ ะฟัะตะฒััะฐัั MTU โ (IP.Header + UDP.Header + RelaibleUDP.Header)
public readonly int BufferSize;
// ะฑะปะพะบ ัะฟัะฐะฒะปะตะฝะธั ะฟะตัะตะดะฐัะตะน
public readonly ReliableUdpConnectionControlBlock Tcb;
// ะธะฝะบะฐะฟััะปะธััะตั ัะตะทัะปััะฐัั ะฐัะธะฝั
ัะพะฝะฝะพะน ะพะฟะตัะฐัะธะธ ะดะปั BeginSendMessage/EndSendMessage
public readonly AsyncResultSendMessage AsyncResult;
// ะฝะต ะพัะฟัะฐะฒะปััั ะฟะฐะบะตัั ะฟะพะดัะฒะตัะถะดะตะฝะธั
public bool IsNoAnswerNeeded;
// ะฟะพัะปะตะดะฝะธะน ะบะพััะตะบัะฝะพ ะฟะพะปััะตะฝะฝัะน ะฟะฐะบะตั (ะฒัะตะณะดะฐ ัััะฐะฝะฐะฒะปะธะฒะฐะตััั ะฒ ะฝะฐะธะฑะพะปััะธะน ะฝะพะผะตั)
public int RcvCurrent;
// ะผะฐััะธะฒ ั ะฝะพะผะตัะฐะผะธ ะฟะพัะตััะฝะฝัั
ะฟะฐะบะตัะพะฒ
public int[] LostPackets { get; private set; }
// ะฟัะธัะตะป ะปะธ ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั. ะัะฟะพะปัะทัะตััั ะบะฐะบ bool.
public int IsLastPacketReceived = 0;
//...
}
เปเบฅเบดเบเปเบเบปเปเบฒเปเบเปเบเบฅเบฐเบซเบฑเบ. เบฅเบฑเบ
เบฅเบฑเบเบเบฐเบเบดเบเบฑเบเปเบเบทเปเบญเบเบเบฑเบเบเบญเบเบฅเบฑเบเบเบญเบเบญเบฐเบเบธเบชเบฑเบเบเบฒ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป, เบเปเบญเบเบเบตเปเบเบฒเบเบเบฐเบกเบงเบเบเบปเบเบเบปเปเบเบเปเบเบญเบเปเบเบฑเบเปเบเบฑเบเปเบเบตเบเบเบถเปเบ. เบซเปเบญเบเบฎเบฝเบ abstract ReliableUdpState เบชเบฐเบซเบเบญเบเบเบฒเบเปเบเปเบเบญเบเบชเปเบฒเบฅเบฑเบเบฅเบฑเบ:
เปเบซเบเบเบปเบเบเบฑเบเบซเบกเบปเบเบเบญเบเปเบเปเบเบเบญเบเปเบกเปเบเบเบฐเบเบดเบเบฑเบเปเบเบเบเบฑเปเบเบฎเบฝเบเบเบตเปเบเปเบฒเบชเบฐเปเบซเบเบตเบเปเบฒเบเปเบเบดเบ, เบเปเบญเบกเบเบฑเบเบเบฑเปเบเบเปเบงเบเบเบตเปเบชเบฐเบซเบเบญเบเบงเบดเบเบตเบเบฒเบเบชเบฐเบเบดเบ, เปเบเบฑเปเบ: เบเบฒเบเบชเปเบฒเบเบชเปเบงเบเบซเบปเบง ReliableUdp เบเบฒเบเบเบฑเบเบเบถเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป.
เบเปเปเปเบ, เบเบงเบเปเบฎเบปเบฒเบเบฐเบเบดเบเบฒเบฅเบฐเบเบฒเบขเปเบฒเบเบฅเบฐเบญเบฝเบเบเปเบฝเบงเบเบฑเบเบเบฒเบเบเบฐเบเบดเบเบฑเบเบงเบดเบเบตเบเบฒเบเปเบเปเบเบญเบเบเบตเปเบเปเบฒเบเบปเบเบชเบนเบเบเบฒเบเบเบดเบเปเบฅเปเบเบทเปเบเบเบฒเบเบเบญเบเปเบเปเบเบเบญเบ.
เบงเบดเบเบต DisposeByTimeout
เบงเบดเบเบตเบเบฒเบ DisposeByTimeout เปเบกเปเบเบฎเบฑเบเบเบดเบเบเบญเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเปเบญเบเบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบซเบผเบฑเบเบเบฒเบเบซเบกเบปเบเปเบงเบฅเบฒเปเบฅเบฐเบชเปเบฒเบฅเบฑเบเบชเบฑเบเบเบฒเบเบเบฒเบเบชเบปเปเบเบเปเปเบเบงเบฒเบกเบชเบปเบเบเบปเบเบชเปเบฒเปเบฅเบฑเบ / เบเปเปเบชเปเบฒเปเบฅเบฑเบ.
ReliableUdpState.DisposeByTimeout:
protected virtual void DisposeByTimeout(object record)
{
ReliableUdpConnectionRecord connectionRecord = (ReliableUdpConnectionRecord) record;
if (record.AsyncResult != null)
{
connectionRecord.AsyncResult.SetAsCompleted(false);
}
connectionRecord.Dispose();
}
เบกเบฑเบเบเบฝเบเปเบเป overridden เปเบเบฅเบฑเบ เบชเปเบฒเปเบฅเบฑเบ.
เบชเบณเปเบฅเบฑเบเปเบฅเปเบง.DisposeByTimeout:
protected override void DisposeByTimeout(object record)
{
ReliableUdpConnectionRecord connectionRecord = (ReliableUdpConnectionRecord) record;
// ัะพะพะฑัะฐะตะผ ะพะฑ ััะฟะตัะฝะพะผ ะฟะพะปััะตะฝะธะธ ัะพะพะฑัะตะฝะธั
SetAsCompleted(connectionRecord);
}
ProcessPackets เบงเบดเบเบตเบเบฒเบ
เบงเบดเบเบตเบเบฒเบ ProcessPackets เปเบกเปเบเบฎเบฑเบเบเบดเบเบเบญเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบฐเบกเบงเบเบเบปเบเปเบเบตเปเบกเปเบเบตเบกเบเบญเบเบเบธเบเบซเบผเบทเบเบธเบ. เปเบเบซเบฒเปเบเบเบเบปเบเบซเบผเบทเบเปเบฒเบเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเบฅเปเบเปเบฒเปเบเบฑเบเปเบเบฑเบ.
เบชเบฒเบกเบฒเบ เบเบฒเบเบเบดเบเบเบฑเปเบ เบงเบดเบเบตเบเบฒเบเปเบกเปเบ overridden เปเบฅเบฐเบฎเบฑเบเบเบดเบเบเบญเบเปเบเบเบฒเบเบเบงเบเบชเบญเบเบเบธเบเบเบตเปเบชเบนเบเปเบชเบเปเบฅเบฐเบเบฒเบเบซเบฑเบเบเปเบฝเบเปเบเบชเบนเปเบฅเบฑเบ เบชเปเบฒเปเบฅเบฑเบ, เปเบเบเปเบฅเบฐเบเบตเบเบตเปเปเบเปเบฎเบฑเบเบเบญเบเบชเบธเบเบเปเบฒเบเปเบฅเบฐเบเปเบฒเบเบเบฒเบเบเบงเบเบชเบญเบเบชเบปเบเบเบปเบเบชเปเบฒเปเบฅเบฑเบ
Assembling.ProcessPackets:
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
if (connectionRecord.IsDone != 0)
return;
if (!ReliableUdpStateTools.CheckForNoPacketLoss(connectionRecord, connectionRecord.IsLastPacketReceived != 0))
{
// ะตััั ะฟะพัะตััะฝะฝัะต ะฟะฐะบะตัั, ะพัััะปะฐะตะผ ะทะฐะฟัะพัั ะฝะฐ ะฝะธั
foreach (int seqNum in connectionRecord.LostPackets)
{
if (seqNum != 0)
{
ReliableUdpStateTools.SendAskForLostPacket(connectionRecord, seqNum);
}
}
// ัััะฐะฝะฐะฒะปะธะฒะฐะตะผ ัะฐะนะผะตั ะฒะพ ะฒัะพัะพะน ัะฐะท, ะดะปั ะฟะพะฒัะพัะฝะพะน ะฟะพะฟััะบะธ ะฟะตัะตะดะฐัะธ
if (!connectionRecord.TimerSecondTry)
{
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
connectionRecord.TimerSecondTry = true;
return;
}
// ะตัะปะธ ะฟะพัะปะต ะดะฒัั
ะฟะพะฟััะพะบ ััะฐะฑะฐััะฒะฐะฝะธะน WaitForPacketTimer
// ะฝะต ัะดะฐะปะพัั ะฟะพะปััะธัั ะฟะฐะบะตัั - ะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะทะฐะฒะตััะตะฝะธั ัะพะตะดะธะฝะตะฝะธั
StartCloseWaitTimer(connectionRecord);
}
else if (connectionRecord.IsLastPacketReceived != 0)
// ััะฟะตัะฝะฐั ะฟัะพะฒะตัะบะฐ
{
// ะฒัััะปะฐะตะผ ะฟะพะดัะฒะตัะถะดะตะฝะธะต ะพ ะฟะพะปััะตะฝะธะธ ะฑะปะพะบะฐ ะดะฐะฝะฝัั
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
connectionRecord.State = connectionRecord.Tcb.States.Completed;
connectionRecord.State.ProcessPackets(connectionRecord);
// ะฒะผะตััะพ ะผะพะผะตะฝัะฐะปัะฝะพะน ัะตะฐะปะธะทะฐัะธะธ ัะตััััะพะฒ
// ะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั, ะฝะฐ ัะปััะฐะน, ะตัะปะธ
// ะตัะปะธ ะฟะพัะปะตะดะฝะธะน ack ะฝะต ะดะพะนะดะตั ะดะพ ะพัะฟัะฐะฒะธัะตะปั ะธ ะพะฝ ะทะฐะฟัะพัะธั ะตะณะพ ัะฝะพะฒะฐ.
// ะฟะพ ััะฐะฑะฐััะฒะฐะฝะธั ัะฐะนะผะตัะฐ - ัะตะฐะปะธะทัะตะผ ัะตััััั
// ะฒ ัะพััะพัะฝะธะธ Completed ะผะตัะพะด ัะฐะนะผะตัะฐ ะฟะตัะตะพะฟัะตะดะตะปะตะฝ
StartCloseWaitTimer(connectionRecord);
}
// ััะพ ัะปััะฐะน, ะบะพะณะดะฐ ack ะฝะฐ ะฑะปะพะบ ะฟะฐะบะตัะพะฒ ะฑัะป ะฟะพัะตััะฝ
else
{
if (!connectionRecord.TimerSecondTry)
{
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
connectionRecord.TimerSecondTry = true;
return;
}
// ะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะทะฐะฒะตััะตะฝะธั ัะพะตะดะธะฝะตะฝะธั
StartCloseWaitTimer(connectionRecord);
}
}
เบชเบฒเบกเบฒเบ เบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ เบงเบดเบเบตเบเบฒเบเบเบตเปเปเบกเปเบเปเบญเบตเปเบเบงเปเบฒเบเบฝเบเปเบเปเบเบฑเบเปเบงเบฅเบฒ, เปเบฅเบฐเบฎเบฑเบเบเบดเบเบเบญเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบปเปเบเบเบทเบเบเปเปเบเบงเบฒเบกเบชเบธเบเบเปเบฒเบ, เปเบเบฑเปเบเบเบฝเบงเบเบฑเบเบเบฑเบเบเบฒเบเปเบฎเบฑเบเปเบซเปเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเบเปเบงเบฅเบฒเปเบเปเบเบดเบ.
SendingCycle.ProcessPackets:
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
if (connectionRecord.IsDone != 0)
return;
// ะพัะฟัะฐะฒะปัะตะผ ะฟะพะฒัะพัะฝะพ ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั
// ( ะฒ ัะปััะฐะต ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ัะพะตะดะธะฝะตะฝะธั ัะทะตะป-ะฟัะธะตะผะฝะธะบ ะทะฐะฝะพะฒะพ ะพัะฟัะฐะฒะธั ะทะฐะฟัะพัั, ะบะพัะพััะต ะดะพ ะฝะตะณะพ ะฝะต ะดะพัะปะธ)
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.RetransmissionCreateUdpPayload(connectionRecord, connectionRecord.SndNext - 1));
// ะฒะบะปััะฐะตะผ ัะฐะนะผะตั CloseWait โ ะดะปั ะพะถะธะดะฐะฝะธั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ัะพะตะดะธะฝะตะฝะธั ะธะปะธ ะตะณะพ ะทะฐะฒะตััะตะฝะธั
StartCloseWaitTimer(connectionRecord);
}
เบชเบฒเบกเบฒเบ เบชเปเบฒเปเบฅเบฑเบ เบงเบดเบเบตเบเบฒเบเบขเบธเบเปเบเบปเบฒเบเบฒเบเบเบฑเบเปเบงเบฅเบฒเปเบฅเปเบเปเบฅเบฐเบชเบปเปเบเบเปเปเบเบงเบฒเบกเปเบเบซเบฒเบเบนเปเบเบญเบ.
เบชเบณเปเบฅเบฑเบเปเบฅเปเบง.ProcessPackets:
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
if (connectionRecord.WaitForPacketsTimer != null)
connectionRecord.WaitForPacketsTimer.Dispose();
// ัะพะฑะธัะฐะตะผ ัะพะพะฑัะตะฝะธะต ะธ ะฟะตัะตะดะฐะตะผ ะตะณะพ ะฟะพะดะฟะธััะธะบะฐะผ
ReliableUdpStateTools.CreateMessageFromMemoryStream(connectionRecord);
}
เบงเบดเบเบตเบเบฒเบเบฎเบฑเบ Packet
เบชเบฒเบกเบฒเบ FirstPacket เปเบเปเบฎเบฑเบ เบงเบฝเบเบเบฒเบเบเบปเปเบเบเปเบเบญเบเบงเบดเบเบตเบเบฒเบเปเบกเปเบเปเบเบทเปเบญเบเปเบฒเบเบปเบเบงเปเบฒเบเบธเบเบเปเปเบเบงเบฒเบกเบเปเบฒเบญเบดเบเบกเบฒเบฎเบญเบเปเบเบเบฒเบเปเบเปเบเบญเบ, เปเบฅเบฐเบเบฑเบเปเบเบฑเบเบเปเบฒเบเปเปเบเบงเบฒเบกเบเบตเปเบเบฐเบเบญเบเบเปเบงเบเบเบญเบเบเบฝเบง.
FirstPacketReceived.ReceivePacket:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
if (!header.Flags.HasFlag(ReliableUdpHeaderFlags.FirstPacket))
// ะพัะฑัะฐััะฒะฐะตะผ ะฟะฐะบะตั
return;
// ะบะพะผะฑะธะฝะฐัะธั ะดะฒัั
ัะปะฐะณะพะฒ - FirstPacket ะธ LastPacket - ะณะพะฒะพัะธั ััะพ ั ะฝะฐั ะตะดะธะฝััะฒะตะฝะฝะพะต ัะพะพะฑัะตะฝะธะต
if (header.Flags.HasFlag(ReliableUdpHeaderFlags.FirstPacket) &
header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
{
ReliableUdpStateTools.CreateMessageFromSinglePacket(connectionRecord, header, payload.Slice(ReliableUdpHeader.Length, payload.Length));
if (!header.Flags.HasFlag(ReliableUdpHeaderFlags.NoAsk))
{
// ะพัะฟัะฐะฒะปัะตะผ ะฟะฐะบะตั ะฟะพะดัะฒะตัะถะดะตะฝะธะต
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
}
SetAsCompleted(connectionRecord);
return;
}
// by design ะฒัะต packet numbers ะฝะฐัะธะฝะฐัััั ั 0;
if (header.PacketNumber != 0)
return;
ReliableUdpStateTools.InitIncomingBytesStorage(connectionRecord, header);
ReliableUdpStateTools.WritePacketData(connectionRecord, header, payload);
// ััะธัะฐะตะผ ะบะพะป-ะฒะพ ะฟะฐะบะตัะพะฒ, ะบะพัะพััะต ะดะพะปะถะฝั ะฟัะธะนัะธ
connectionRecord.NumberOfPackets = (int)Math.Ceiling((double) ((double) connectionRecord.IncomingStream.Length/(double) connectionRecord.BufferSize));
// ะทะฐะฟะธััะฒะฐะตะผ ะฝะพะผะตั ะฟะพัะปะตะดะฝะตะณะพ ะฟะพะปััะตะฝะฝะพะณะพ ะฟะฐะบะตัะฐ (0)
connectionRecord.RcvCurrent = header.PacketNumber;
// ะฟะพัะปะต ัะดะฒะธะฝัะปะธ ะพะบะฝะพ ะฟัะธะตะผะฐ ะฝะฐ 1
connectionRecord.WindowLowerBound++;
// ะฟะตัะตะบะปััะฐะตะผ ัะพััะพัะฝะธะต
connectionRecord.State = connectionRecord.Tcb.States.Assembling;
// ะตัะปะธ ะฝะต ััะตะฑัะตััั ะผะตั
ะฐะฝะธะทะผ ะฟะพะดัะฒะตัะถะดะตะฝะธะต
// ะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะบะพัะพััะน ะฒััะฒะพะฑะพะดะธั ะฒัะต ััััะบัััั
if (header.Flags.HasFlag(ReliableUdpHeaderFlags.NoAsk))
{
connectionRecord.CloseWaitTimer = new Timer(DisposeByTimeout, connectionRecord, connectionRecord.ShortTimerPeriod, -1);
}
else
{
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
connectionRecord.WaitForPacketsTimer = new Timer(CheckByTimer, connectionRecord, connectionRecord.ShortTimerPeriod, -1);
}
}
เบชเบฒเบกเบฒเบ เบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ เบงเบดเบเบตเบเบฒเบเบเบตเปเปเบกเปเบ overridden เปเบเบทเปเบญเบเบญเบกเบฎเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเปเบฅเบฐเบเบฒเบเบฎเปเบญเบเบเป retransmission.
SendingCycle.ReceivePacket:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
if (connectionRecord.IsDone != 0)
return;
if (!header.Flags.HasFlag(ReliableUdpHeaderFlags.RequestForPacket))
return;
// ัะฐััะตั ะบะพะฝะตัะฝะพะน ะณัะฐะฝะธัั ะพะบะฝะฐ
// ะฑะตัะตััั ะณัะฐะฝะธัะฐ ะพะบะฝะฐ + 1, ะดะปั ะฟะพะปััะตะฝะธั ะฟะพะดัะฒะตัะถะดะตะฝะธะน ะดะพััะฐะฒะบะธ
int windowHighestBound = Math.Min((connectionRecord.WindowLowerBound + connectionRecord.WindowSize), (connectionRecord.NumberOfPackets));
// ะฟัะพะฒะตัะบะฐ ะฝะฐ ะฟะพะฟะฐะดะฐะฝะธะต ะฒ ะพะบะฝะพ
if (header.PacketNumber < connectionRecord.WindowLowerBound || header.PacketNumber > windowHighestBound)
return;
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
if (connectionRecord.CloseWaitTimer != null)
connectionRecord.CloseWaitTimer.Change(-1, -1);
// ะฟัะพะฒะตัะธัั ะฝะฐ ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั:
if (header.PacketNumber == connectionRecord.NumberOfPackets)
{
// ะฟะตัะตะดะฐัะฐ ะทะฐะฒะตััะตะฝะฐ
Interlocked.Increment(ref connectionRecord.IsDone);
SetAsCompleted(connectionRecord);
return;
}
// ััะพ ะพัะฒะตั ะฝะฐ ะฟะตัะฒัะน ะฟะฐะบะตั c ะฟะพะดัะฒะตัะถะดะตะฝะธะตะผ
if ((header.Flags.HasFlag(ReliableUdpHeaderFlags.FirstPacket) && header.PacketNumber == 1))
{
// ะฑะตะท ัะดะฒะธะณะฐ ะพะบะฝะฐ
SendPacket(connectionRecord);
}
// ะฟัะธัะปะพ ะฟะพะดัะฒะตัะถะดะตะฝะธะต ะพ ะฟะพะปััะตะฝะธะธ ะฑะปะพะบะฐ ะดะฐะฝะฝัั
else if (header.PacketNumber == windowHighestBound)
{
// ัะดะฒะธะณะฐะตะผ ะพะบะฝะพ ะฟัะธะตะผ/ะฟะตัะตะดะฐัะธ
connectionRecord.WindowLowerBound += connectionRecord.WindowSize;
// ะพะฑะฝัะปัะตะผ ะผะฐััะธะฒ ะบะพะฝััะพะปั ะฟะตัะตะดะฐัะธ
connectionRecord.WindowControlArray.Nullify();
// ะพัะฟัะฐะฒะปัะตะผ ะฑะปะพะบ ะฟะฐะบะตัะพะฒ
SendPacket(connectionRecord);
}
// ััะพ ะทะฐะฟัะพั ะฝะฐ ะฟะพะฒัะพัะฝัั ะฟะตัะตะดะฐัั โ ะพัะฟัะฐะฒะปัะตะผ ััะตะฑัะตะผัะน ะฟะฐะบะตั
else
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.RetransmissionCreateUdpPayload(connectionRecord, header.PacketNumber));
}
เบชเบฒเบกเบฒเบ เบเบฒเบเบเบดเบเบเบฑเปเบ เปเบเบงเบดเบเบตเบเบฒเบ ReceivePacket, เบเบฒเบเปเบฎเบฑเบเบงเบฝเบเบเบปเปเบเบเปเบเบญเบเบเบฒเบเบเบฐเบเบญเบเบเปเปเบเบงเบฒเบกเบเบฒเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเปเบเบปเปเบฒเบกเบฒเปเบกเปเบเปเบเบตเบเบเบทเปเบ.
Assembling.ReceivePacket:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
if (connectionRecord.IsDone != 0)
return;
// ะพะฑัะฐะฑะพัะบะฐ ะฟะฐะบะตัะพะฒ ั ะพัะบะปััะตะฝะฝัะผ ะผะตั
ะฐะฝะธะทะผะพะผ ะฟะพะดัะฒะตัะถะดะตะฝะธั ะดะพััะฐะฒะบะธ
if (header.Flags.HasFlag(ReliableUdpHeaderFlags.NoAsk))
{
// ัะฑัะฐััะฒะฐะตะผ ัะฐะนะผะตั
connectionRecord.CloseWaitTimer.Change(connectionRecord.LongTimerPeriod, -1);
// ะทะฐะฟะธััะฒะฐะตะผ ะดะฐะฝะฝัะต
ReliableUdpStateTools.WritePacketData(connectionRecord, header, payload);
// ะตัะปะธ ะฟะพะปััะธะปะธ ะฟะฐะบะตั ั ะฟะพัะปะตะดะฝะธะผ ัะปะฐะณะพะผ - ะดะตะปะฐะตะผ ะทะฐะฒะตััะฐะตะผ
if (header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
{
connectionRecord.State = connectionRecord.Tcb.States.Completed;
connectionRecord.State.ProcessPackets(connectionRecord);
}
return;
}
// ัะฐััะตั ะบะพะฝะตัะฝะพะน ะณัะฐะฝะธัั ะพะบะฝะฐ
int windowHighestBound = Math.Min((connectionRecord.WindowLowerBound + connectionRecord.WindowSize - 1), (connectionRecord.NumberOfPackets - 1));
// ะพัะฑัะฐััะฒะฐะตะผ ะฝะต ะฟะพะฟะฐะดะฐััะธะต ะฒ ะพะบะฝะพ ะฟะฐะบะตัั
if (header.PacketNumber < connectionRecord.WindowLowerBound || header.PacketNumber > (windowHighestBound))
return;
// ะพัะฑัะฐััะฒะฐะตะผ ะดัะฑะปะธะบะฐัั
if (connectionRecord.WindowControlArray.Contains(header.PacketNumber))
return;
// ะทะฐะฟะธััะฒะฐะตะผ ะดะฐะฝะฝัะต
ReliableUdpStateTools.WritePacketData(connectionRecord, header, payload);
// ัะฒะตะปะธัะธะฒะฐะตะผ ััะตััะธะบ ะฟะฐะบะตัะพะฒ
connectionRecord.PacketCounter++;
// ะทะฐะฟะธััะฒะฐะตะผ ะฒ ะผะฐััะธะฒ ัะฟัะฐะฒะปะตะฝะธั ะพะบะฝะพะผ ัะตะบััะธะน ะฝะพะผะตั ะฟะฐะบะตัะฐ
connectionRecord.WindowControlArray[header.PacketNumber - connectionRecord.WindowLowerBound] = header.PacketNumber;
// ัััะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฝะฐะธะฑะพะปััะธะน ะฟัะธัะตะดัะธะน ะฟะฐะบะตั
if (header.PacketNumber > connectionRecord.RcvCurrent)
connectionRecord.RcvCurrent = header.PacketNumber;
// ะฟะตัะตะทะฐะฟััะบะฐะผ ัะฐะนะผะตัั
connectionRecord.TimerSecondTry = false;
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
if (connectionRecord.CloseWaitTimer != null)
connectionRecord.CloseWaitTimer.Change(-1, -1);
// ะตัะปะธ ะฟัะธัะตะป ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั
if (header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
{
Interlocked.Increment(ref connectionRecord.IsLastPacketReceived);
}
// ะตัะปะธ ะฝะฐะผ ะฟัะธัะปะธ ะฒัะต ะฟะฐะบะตัั ะพะบะฝะฐ, ัะพ ัะฑัะฐััะฒะฐะตะผ ััะตััะธะบ
// ะธ ะฒัััะปะฐะตะผ ะฟะฐะบะตั ะฟะพะดัะฒะตัะถะดะตะฝะธะต
else if (connectionRecord.PacketCounter == connectionRecord.WindowSize)
{
// ัะฑัะฐััะฒะฐะตะผ ััะตััะธะบ.
connectionRecord.PacketCounter = 0;
// ัะดะฒะธะฝัะปะธ ะพะบะฝะพ ะฟะตัะตะดะฐัะธ
connectionRecord.WindowLowerBound += connectionRecord.WindowSize;
// ะพะฑะฝัะปะตะฝะธะต ะผะฐััะธะฒะฐ ัะฟัะฐะฒะปะตะฝะธั ะฟะตัะตะดะฐัะตะน
connectionRecord.WindowControlArray.Nullify();
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
}
// ะตัะปะธ ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั ัะถะต ะธะผะตะตััั
if (Thread.VolatileRead(ref connectionRecord.IsLastPacketReceived) != 0)
{
// ะฟัะพะฒะตััะตะผ ะฟะฐะบะตัั
ProcessPackets(connectionRecord);
}
}
เบชเบฒเบกเบฒเบ เบชเปเบฒเปเบฅเบฑเบ เบงเบฝเบเบเบฒเบเบเบฝเบงเบเบญเบเบงเบดเบเบตเบเบฒเบเปเบกเปเบเปเบเบทเปเบญเบชเบปเปเบเบเบฒเบเบฎเบฑเบเบฎเบนเปเบเบทเบเปเบซเบกเปเบเบญเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบชเบปเบเบเบปเบเบชเปเบฒเปเบฅเบฑเบเบเบญเบเบเปเปเบเบงเบฒเบก.
เบชเบณเปเบฅเบฑเบเปเบฅเปเบง.ReceivePacket:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
// ะฟะพะฒัะพัะฝะฐั ะพัะฟัะฐะฒะบะฐ ะฟะพัะปะตะดะฝะตะณะพ ะฟะฐะบะตัะฐ ะฒ ัะฒัะทะธ ั ัะตะผ,
// ััะพ ะฟะพัะปะตะดะฝะธะน ack ะฝะต ะดะพัะตะป ะดะพ ะพัะฟัะฐะฒะธัะตะปั
if (header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
{
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
}
}
เบชเบปเปเบเบงเบดเบเบตเบเบฒเบเบซเบธเปเบกเบซเปเป
เบชเบฒเบกเบฒเบ FirstPacketSending เบงเบดเบเบตเบเบฒเบเบเบตเปเบชเบปเปเบเบเปเปเบกเบนเบเบเบธเบเบเปเบฒเบญเบดเบ, เบซเบผเบทเบเปเบฒเบเปเปเบเบงเบฒเบกเบเปเปเบเปเบญเบเบเบฒเบเบเบฒเบเบขเบทเบเบขเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบ, เบเปเปเบเบงเบฒเบกเบเบฑเบเบซเบกเบปเบ.
FirstPacketSending.SendPacket:
public override void SendPacket(ReliableUdpConnectionRecord connectionRecord)
{
connectionRecord.PacketCounter = 0;
connectionRecord.SndNext = 0;
connectionRecord.WindowLowerBound = 0;
// ะตัะปะธ ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฝะต ััะตะฑัะตััั - ะพัะฟัะฐะฒะปัะตะผ ะฒัะต ะฟะฐะบะตัั
// ะธ ะฒััะฒะพะฑะพะถะดะฐะตะผ ัะตััััั
if (connectionRecord.IsNoAnswerNeeded)
{
// ะะดะตัั ะฟัะพะธัั
ะพะดะธั ะพัะฟัะฐะฒะบะฐ As Is
do
{
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.CreateUdpPayload(connectionRecord, ReliableUdpStateTools. CreateReliableUdpHeader(connectionRecord)));
connectionRecord.SndNext++;
} while (connectionRecord.SndNext < connectionRecord.NumberOfPackets);
SetAsCompleted(connectionRecord);
return;
}
// ัะพะทะดะฐะตะผ ะทะฐะณะพะปะพะฒะพะบ ะฟะฐะบะตัะฐ ะธ ะพัะฟัะฐะฒะปัะตะผ ะตะณะพ
ReliableUdpHeader header = ReliableUdpStateTools.CreateReliableUdpHeader(connectionRecord);
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.CreateUdpPayload(connectionRecord, header));
// ัะฒะตะปะธัะธะฒะฐะตะผ ััะตััะธะบ
connectionRecord.SndNext++;
// ัะดะฒะธะณะฐะตะผ ะพะบะฝะพ
connectionRecord.WindowLowerBound++;
connectionRecord.State = connectionRecord.Tcb.States.SendingCycle;
// ะะฐะฟััะบะฐะตะผ ัะฐะนะผะตั
connectionRecord.WaitForPacketsTimer = new Timer(CheckByTimer, connectionRecord, connectionRecord.ShortTimerPeriod, -1);
}
เบชเบฒเบกเบฒเบ เบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ เปเบเบงเบดเบเบตเบเบฒเบเบเบตเป, เบเบฑเบเบเบญเบเปเบเบฑเบเปเบเบฑเบเบเบทเบเบชเบปเปเบ.
SendingCycle.SendPacket:
public override void SendPacket(ReliableUdpConnectionRecord connectionRecord)
{
// ะพัะฟัะฐะฒะปัะตะผ ะฑะปะพะบ ะฟะฐะบะตัะพะฒ
for (connectionRecord.PacketCounter = 0;
connectionRecord.PacketCounter < connectionRecord.WindowSize &&
connectionRecord.SndNext < connectionRecord.NumberOfPackets;
connectionRecord.PacketCounter++)
{
ReliableUdpHeader header = ReliableUdpStateTools.CreateReliableUdpHeader(connectionRecord);
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.CreateUdpPayload(connectionRecord, header));
connectionRecord.SndNext++;
}
// ะฝะฐ ัะปััะฐะน ะฑะพะปััะพะณะพ ะพะบะฝะฐ ะฟะตัะตะดะฐัะธ, ะฟะตัะตะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะฟะพัะปะต ะพัะฟัะฐะฒะบะธ
connectionRecord.WaitForPacketsTimer.Change( connectionRecord.ShortTimerPeriod, -1 );
if ( connectionRecord.CloseWaitTimer != null )
{
connectionRecord.CloseWaitTimer.Change( -1, -1 );
}
}
เปเบฅเบดเบเปเบเบปเปเบฒเปเบเปเบเบฅเบฐเบซเบฑเบ. เบเบฒเบเบชเปเบฒเบเปเบฅเบฐเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป
เปเบเบเบฑเบเบเบธเบเบฑเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเปเบเปเปเบซเบฑเบเบฅเบฑเบเบเบทเปเบเบเบฒเบเปเบฅเบฐเบงเบดเบเบตเบเบฒเบเบเบตเปเปเบเปเปเบเบเบฒเบเบเบฑเบเบเบฒเบเบฅเบฑเบ, เปเบซเปเบเบงเบเปเบฎเบปเบฒเบเปเบฒเบฅเบฒเบเบเบปเบงเบขเปเบฒเบเบเปเบฒเบเบงเบเบซเบเปเบญเบเบเบญเบเบงเบดเบเบตเบเบฒเบเปเบฎเบฑเบเบงเบฝเบเบเบญเบเปเบเปเบเบเบญเบเปเบเบฅเบฒเบเบฅเบฐเบญเบฝเบเปเบเบตเปเบกเปเบเบตเบก.
เปเบเบเบงเบฒเบเบเบฒเบเบชเบปเปเบเบเปเปเบกเบนเบเบเบฒเบเปเบเปเปเบเบทเปเบญเบเปเบเบเบปเบเบเบฐเบเบด:
เบเบดเบเบฒเบฅเบฐเบเบฒเบฅเบฒเบเบฅเบฐเบญเบฝเบเบเบฒเบเบชเปเบฒเบ เบเบฑเบเบเบถเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป เปเบเบทเปเบญเปเบเบทเปเบญเบกเบเปเปเปเบฅเบฐเบชเบปเปเบเบเบธเบเบเปเบฒเบญเบดเบ. เบเบฒเบเปเบญเบเบเปเบฒเบเปเบกเปเบเปเบฅเบตเปเบกเบเบปเปเบเปเบเบเปเบญเบฑเบเบเบฅเบดเปเบเบเบฑเบเบเบตเปเปเบญเบตเปเบ API เบชเบปเปเบเบเปเปเบเบงเบฒเบก. เบเปเปเปเบ, เบงเบดเบเบตเบเบฒเบ StartTransmission เบเบญเบเบเบฑเบเบเบงเบเบเบธเบกเบฅเบฐเบเบปเบเบชเบฒเบเบชเบปเปเบเปเบกเปเบ invoked, เปเบเบดเปเบเปเบฅเบตเปเบกเบเบปเปเบเบเบฒเบเบชเบปเปเบเบเปเปเบกเบนเบเบชเปเบฒเบฅเบฑเบเบเปเปเบเบงเบฒเบกเปเบซเบกเป.
เบเบฒเบเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเบญเบญเบ:
private void StartTransmission(ReliableUdpMessage reliableUdpMessage, EndPoint endPoint, AsyncResultSendMessage asyncResult)
{
if (m_isListenerStarted == 0)
{
if (this.LocalEndpoint == null)
{
throw new ArgumentNullException( "", "You must use constructor with parameters or start listener before sending message" );
}
// ะทะฐะฟััะบะฐะตะผ ะพะฑัะฐะฑะพัะบั ะฒั
ะพะดััะธั
ะฟะฐะบะตัะพะฒ
StartListener(LocalEndpoint);
}
// ัะพะทะดะฐะตะผ ะบะปัั ะดะปั ัะปะพะฒะฐัั, ะฝะฐ ะพัะฝะพะฒะต EndPoint ะธ ReliableUdpHeader.TransmissionId
byte[] transmissionId = new byte[4];
// ัะพะทะดะฐะตะผ ัะปััะฐะนะฝัะน ะฝะพะผะตั transmissionId
m_randomCrypto.GetBytes(transmissionId);
Tuple<EndPoint, Int32> key = new Tuple<EndPoint, Int32>(endPoint, BitConverter.ToInt32(transmissionId, 0));
// ัะพะทะดะฐะตะผ ะฝะพะฒัั ะทะฐะฟะธัั ะดะปั ัะพะตะดะธะฝะตะฝะธั ะธ ะฟัะพะฒะตััะตะผ,
// ัััะตััะฒัะตั ะปะธ ัะถะต ัะฐะบะพะน ะฝะพะผะตั ะฒ ะฝะฐัะธั
ัะปะพะฒะฐััั
if (!m_listOfHandlers.TryAdd(key, new ReliableUdpConnectionRecord(key, this, reliableUdpMessage, asyncResult)))
{
// ะตัะปะธ ัััะตััะฒัะตั โ ัะพ ะฟะพะฒัะพัะฝะพ ะณะตะฝะตัะธััะตะผ ัะปััะฐะนะฝัะน ะฝะพะผะตั
m_randomCrypto.GetBytes(transmissionId);
key = new Tuple<EndPoint, Int32>(endPoint, BitConverter.ToInt32(transmissionId, 0));
if (!m_listOfHandlers.TryAdd(key, new ReliableUdpConnectionRecord(key, this, reliableUdpMessage, asyncResult)))
// ะตัะปะธ ัะฝะพะฒะฐ ะฝะต ัะดะฐะปะพัั โ ะณะตะฝะตัะธััะตะผ ะธัะบะปััะตะฝะธะต
throw new ArgumentException("Pair TransmissionId & EndPoint is already exists in the dictionary");
}
// ะทะฐะฟัััะธะปะธ ัะพััะพัะฝะธะต ะฒ ะพะฑัะฐะฑะพัะบั
m_listOfHandlers[key].State.SendPacket(m_listOfHandlers[key]);
}
เบเบฒเบเบชเบปเปเบเปเบเบฑเบเปเบเบฑเบเบเปเบฒเบญเบดเบ (FirstPacketSending state):
public override void SendPacket(ReliableUdpConnectionRecord connectionRecord)
{
connectionRecord.PacketCounter = 0;
connectionRecord.SndNext = 0;
connectionRecord.WindowLowerBound = 0;
// ...
// ัะพะทะดะฐะตะผ ะทะฐะณะพะปะพะฒะพะบ ะฟะฐะบะตัะฐ ะธ ะพัะฟัะฐะฒะปัะตะผ ะตะณะพ
ReliableUdpHeader header = ReliableUdpStateTools.CreateReliableUdpHeader(connectionRecord);
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.CreateUdpPayload(connectionRecord, header));
// ัะฒะตะปะธัะธะฒะฐะตะผ ััะตััะธะบ
connectionRecord.SndNext++;
// ัะดะฒะธะณะฐะตะผ ะพะบะฝะพ
connectionRecord.WindowLowerBound++;
// ะฟะตัะตั
ะพะดะธะผ ะฒ ัะพััะพัะฝะธะต SendingCycle
connectionRecord.State = connectionRecord.Tcb.States.SendingCycle;
// ะะฐะฟััะบะฐะตะผ ัะฐะนะผะตั
connectionRecord.WaitForPacketsTimer = new Timer(CheckByTimer, connectionRecord, connectionRecord.ShortTimerPeriod, -1);
}
เบซเบผเบฑเบเบเบฒเบเบชเบปเปเบเบเบธเบเบเปเบฒเบญเบดเบ, เบเบนเปเบชเบปเปเบเปเบเบปเปเบฒเปเบเปเบเบฅเบฑเบ เบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ - เบฅเปโเบเปเบฒโเบชเปเบฒโเบฅเบฑเบโเบเบฒเบโเบขเบทเบโเบขเบฑเบโเบเบฒเบโเบเบฑเบโเบชเบปเปเบโเบเบธเบโ.
เบเปเบฒเบเบเบตเปเปเบเปเบฎเบฑเบ, เปเบเบเปเบเปเบงเบดเบเบตเบเบฒเบ EndReceive, เบฎเบฑเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบปเปเบ, เบชเปเบฒเบเปเบซเบกเป เบเบฑเบเบเบถเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป เปเบฅเบฐเบชเบปเปเบเบเปเปเปเบเบฑเบเปเบเบฑเบเบเบตเป, เปเบเบเบกเบตเบชเปเบงเบเบซเบปเบงเบเบตเปเปเบเบเบเปเบญเบ, เปเบเบซเบฒเบงเบดเบเบตเบเบฒเบเบฎเบฑเบเปเบเบฑเบเปเบเบฑเบเบเบญเบเบฅเบฑเบเบชเบณเบฅเบฑเบเบเบฒเบเบเบฐเบกเบงเบเบเบปเบ. FirstPacket เปเบเปเบฎเบฑเบ
เบเบฒเบเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบขเบนเปเบเปเบฒเบเบเบฒเบเบฎเบฑเบ:
private void EndReceive(IAsyncResult ar)
{
// ...
// ะฟะฐะบะตั ะฟะพะปััะตะฝ
// ะฟะฐััะธะผ ะทะฐะณะพะปะพะฒะพะบ ะฟะฐะบะตัะฐ
ReliableUdpHeader header;
if (!ReliableUdpStateTools.ReadReliableUdpHeader(bytes, out header))
{
// ะฟัะธัะตะป ะฝะตะบะพััะตะบัะฝัะน ะฟะฐะบะตั - ะพัะฑัะฐััะฒะฐะตะผ ะตะณะพ
return;
}
// ะบะพะฝััััะธััะตะผ ะบะปัั ะดะปั ะพะฟัะตะดะตะปะตะฝะธั connection recordโะฐ ะดะปั ะฟะฐะบะตัะฐ
Tuple<EndPoint, Int32> key = new Tuple<EndPoint, Int32>(connectedClient, header.TransmissionId);
// ะฟะพะปััะฐะตะผ ัััะตััะฒััััั connection record ะธะปะธ ัะพะทะดะฐะตะผ ะฝะพะฒัั
ReliableUdpConnectionRecord record = m_listOfHandlers.GetOrAdd(key, new ReliableUdpConnectionRecord(key, this, header. ReliableUdpMessageType));
// ะทะฐะฟััะบะฐะตะผ ะฟะฐะบะตั ะฒ ะพะฑัะฐะฑะพัะบั ะฒ ะบะพะฝะตัะฝัะน ะฐะฒัะพะผะฐั
record.State.ReceivePacket(record, header, bytes);
}
เบเบฒเบโเปเบเปโเบฎเบฑเบโเบเบญเบโเบเปเบฒโเบญเบดเบโเปเบฅเบฐโเบเบฒเบโเบชเบปเปเบโเบเบฒเบโเบฎเบฑเบโเบฎเบนเป (FirstPacketReceived เบฅเบฑเบโ)โ:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
if (!header.Flags.HasFlag(ReliableUdpHeaderFlags.FirstPacket))
// ะพัะฑัะฐััะฒะฐะตะผ ะฟะฐะบะตั
return;
// ...
// by design ะฒัะต packet numbers ะฝะฐัะธะฝะฐัััั ั 0;
if (header.PacketNumber != 0)
return;
// ะธะฝะธัะธะฐะปะธะทะธััะตะผ ะผะฐััะธะฒ ะดะปั ั
ัะฐะฝะตะฝะธั ัะฐััะตะน ัะพะพะฑัะตะฝะธั
ReliableUdpStateTools.InitIncomingBytesStorage(connectionRecord, header);
// ะทะฐะฟะธััะฒะฐะตะผ ะดะฐะฝะฝัะต ะฟะฐะบะตั ะฒ ะผะฐััะธะฒ
ReliableUdpStateTools.WritePacketData(connectionRecord, header, payload);
// ััะธัะฐะตะผ ะบะพะป-ะฒะพ ะฟะฐะบะตัะพะฒ, ะบะพัะพััะต ะดะพะปะถะฝั ะฟัะธะนัะธ
connectionRecord.NumberOfPackets = (int)Math.Ceiling((double) ((double) connectionRecord.IncomingStream.Length/(double) connectionRecord.BufferSize));
// ะทะฐะฟะธััะฒะฐะตะผ ะฝะพะผะตั ะฟะพัะปะตะดะฝะตะณะพ ะฟะพะปััะตะฝะฝะพะณะพ ะฟะฐะบะตัะฐ (0)
connectionRecord.RcvCurrent = header.PacketNumber;
// ะฟะพัะปะต ัะดะฒะธะฝัะปะธ ะพะบะฝะพ ะฟัะธะตะผะฐ ะฝะฐ 1
connectionRecord.WindowLowerBound++;
// ะฟะตัะตะบะปััะฐะตะผ ัะพััะพัะฝะธะต
connectionRecord.State = connectionRecord.Tcb.States.Assembling;
if (/*ะตัะปะธ ะฝะต ััะตะฑัะตััั ะผะตั
ะฐะฝะธะทะผ ะฟะพะดัะฒะตัะถะดะตะฝะธะต*/)
// ...
else
{
// ะพัะฟัะฐะฒะปัะตะผ ะฟะพะดัะฒะตัะถะดะตะฝะธะต
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
connectionRecord.WaitForPacketsTimer = new Timer(CheckByTimer, connectionRecord, connectionRecord.ShortTimerPeriod, -1);
}
}
เปเบฅเบดเบเปเบเบปเปเบฒเปเบเปเบเบฅเบฐเบซเบฑเบ. เบเบฒเบเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒ
เบเบฒเบเบเบฑเบเบเบฒเบเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒเปเบกเปเบเบชเปเบงเบเบซเบเบถเปเบเบเบตเปเบชเปเบฒเบเบฑเบเบเบญเบ UDP เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป. เบเบดเบเบฒเบฅเบฐเบเบฒเบเบปเบงเบขเปเบฒเบเบเบตเปเปเบซเบเบเบเบฒเบเบฅเบปเปเบกเปเบซเบฅเบงเปเบฅเบฐเบเบฒเบเบเบฑเบเบชเบปเปเบเบเปเปเบกเบนเบเปเบเบเบฑเบเบชเบญเบเบเบดเบเบเบฒเบเบเบฒเบเปเบเบฑเบเปเบเบฑเบเปเบเบเปเปเปเบเป.
เปเบเบเบเบฑเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเบเบเบฒเบเบซเบกเบปเบเปเบงเบฅเบฒ:
เบเบฑเปเบเบเบตเปเปเบซเบฑเบเปเบเปเบเบฒเบเปเบเบเบงเบฒเบ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบเบญเบเบเบนเปเบชเบปเปเบเปเบฅเบตเปเบกเบเบปเปเบเบเบฑเบเบเบตเบซเบผเบฑเบเบเบฒเบเบเบฒเบเบชเบปเปเบเปเบเบฑเบเปเบเบฑเบ. เบเบตเปเปเบเบตเบเบเบทเปเบเปเบเบงเบดเบเบตเบเบฒเบ SendPacket เบเบญเบเบฅเบฑเบ เบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ.
เปเบเบตเบโเปเบเปโเบเบฒเบโเปเบกเบโเบเบฑเบโเปเบงโเบฅเบฒโเปเบฎเบฑเบโเบงเบฝเบ (SendingCycle state):
public override void SendPacket(ReliableUdpConnectionRecord connectionRecord)
{
// ะพัะฟัะฐะฒะปัะตะผ ะฑะปะพะบ ะฟะฐะบะตัะพะฒ
// ...
// ะฟะตัะตะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะฟะพัะปะต ะพัะฟัะฐะฒะบะธ
connectionRecord.WaitForPacketsTimer.Change( connectionRecord.ShortTimerPeriod, -1 );
if ( connectionRecord.CloseWaitTimer != null )
connectionRecord.CloseWaitTimer.Change( -1, -1 );
}
เปเบฅเบเบฐเปเบงเบฅเบฒเบเบฑเบเปเบงเบฅเบฒเบเบทเบเบเปเบฒเบเบปเบเปเบกเบทเปเบญเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบทเบเบชเปเบฒเบ. ShortTimerPeriod เปเบฅเบตเปเบกเบเบปเปเบเปเบกเปเบ 5 เบงเบดเบเบฒเบเบต. เปเบเบเบปเบงเบขเปเบฒเบ, เบกเบฑเบเบเบทเบเบเปเบฒเบเบปเบเปเบเบฑเบ 1,5 เบงเบดเบเบฒเบเบต.
เบชเปเบฒเบฅเบฑเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเปเบเบปเปเบฒ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฅเบตเปเบกเบเบปเปเบเบซเบผเบฑเบเบเบฒเบเปเบเปเบฎเบฑเบเปเบเบฑเบเปเบเบฑเบเบเปเปเบกเบนเบเบเบฒเปเบเบปเปเบฒเบชเบธเบเบเปเบฒเบ, เบเบตเปเบเบฐเปเบเบตเบเบเบทเปเบเปเบเบงเบดเบเบตเบเบฒเบ ReceivePacket เบเบญเบเบฅเบฑเบ. เบเบฒเบเบเบดเบเบเบฑเปเบ
เปเบเบตเบโเปเบเปโเบเบฒเบโเปเบกเบโเบเบฑเบโเปเบงโเบฅเบฒโเปเบฎเบฑเบโเบงเบฝเบ (เบชเบฐโเบเบฒโเบเบฐโเบเบฒเบโเบเบฐโเบเบญเบโ)โ:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
// ...
// ะฟะตัะตะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตัั
connectionRecord.TimerSecondTry = false;
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
if (connectionRecord.CloseWaitTimer != null)
connectionRecord.CloseWaitTimer.Change(-1, -1);
// ...
}
เบเปเปเบกเบตเปเบเบฑเบเปเบเบฑเบเปเบเปเบกเบฒเบฎเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเปเบเบปเปเบฒเปเบเบเบฐเบเบฐเบเบตเปเบฅเปเบเปเบฒเปเบกเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบ. เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบเปเบเบดเบเบฅเบปเบเปเบฅเบฐเปเบญเบตเปเบเบงเปเบฒเบงเบดเบเบตเบเบฒเบ ProcessPackets, เบเปเบญเบเบเบตเปเบเบธเบเบเบตเปเบชเบนเบเปเบชเบเปเบเปเบเบทเบเบเบปเบเปเบซเบฑเบเปเบฅเบฐเบเบฒเบเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบเปเบเปเบเบทเบเบชเบปเปเบเปเบเบฑเบเบเบฑเปเบเบเปเบฒเบญเบดเบ.
เบเบณเบฅเบฑเบเบชเบปเปเบเบเบณเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบ (เบชเบฐเบเบฒเบเบฐเบเบฐเบเบญเบ):
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
// ...
if (/*ะฟัะพะฒะตัะบะฐ ะฝะฐ ะฟะพัะตััะฝะฝัะต ะฟะฐะบะตัั */)
{
// ะพัะฟัะฐะฒะปัะตะผ ะทะฐะฟัะพัั ะฝะฐ ะฟะพะฒัะพัะฝัั ะดะพััะฐะฒะบั
// ัััะฐะฝะฐะฒะปะธะฒะฐะตะผ ัะฐะนะผะตั ะฒะพ ะฒัะพัะพะน ัะฐะท, ะดะปั ะฟะพะฒัะพัะฝะพะน ะฟะพะฟััะบะธ ะฟะตัะตะดะฐัะธ
if (!connectionRecord.TimerSecondTry)
{
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
connectionRecord.TimerSecondTry = true;
return;
}
// ะตัะปะธ ะฟะพัะปะต ะดะฒัั
ะฟะพะฟััะพะบ ััะฐะฑะฐััะฒะฐะฝะธะน WaitForPacketTimer
// ะฝะต ัะดะฐะปะพัั ะฟะพะปััะธัั ะฟะฐะบะตัั - ะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะทะฐะฒะตััะตะฝะธั ัะพะตะดะธะฝะตะฝะธั
StartCloseWaitTimer(connectionRecord);
}
else if (/*ะฟัะธัะตะป ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั ะธ ััะฟะตัะฝะฐั ะฟัะพะฒะตัะบะฐ */)
{
// ...
StartCloseWaitTimer(connectionRecord);
}
// ะตัะปะธ ack ะฝะฐ ะฑะปะพะบ ะฟะฐะบะตัะพะฒ ะฑัะป ะฟะพัะตััะฝ
else
{
if (!connectionRecord.TimerSecondTry)
{
// ะฟะพะฒัะพัะฝะพ ะพัััะปะฐะตะผ ack
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
connectionRecord.TimerSecondTry = true;
return;
}
// ะทะฐะฟััะบะฐะตะผ ัะฐะนะผะตั ะทะฐะฒะตััะตะฝะธั ัะพะตะดะธะฝะตะฝะธั
StartCloseWaitTimer(connectionRecord);
}
}
เบเบปเบงเปเบ TimerSecondTry เบเบทเบเบเบฑเปเบเปเบเบฑเบ เบเบตเปเปเบเปเบเบดเบ. เบเบปเบงเปเบเบเบตเปเปเบกเปเบเบฎเบฑเบเบเบดเบเบเบญเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเปเบเบตเบเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบเบทเบเปเบซเบกเป.
เบขเบนเปเบเปเบฒเบเบเบนเปเบชเบปเปเบ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบเบฑเบเบเบทเบเบเบฐเบเบธเปเบ เปเบฅเบฐเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบปเปเบเบซเบผเปเบฒเบชเบธเบเบเบทเบเบชเบปเปเบเบเบทเบ.
เปเบเบตเบเปเบเปเบเบปเบงเบเบฑเบเปเบงเบฅเบฒเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป (เบชเบฐเบเบฒเบเบฐเบงเบปเบเบเบญเบเบเบฒเบเบชเบปเปเบ):
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
// ...
// ะพัะฟัะฐะฒะปัะตะผ ะฟะพะฒัะพัะฝะพ ะฟะพัะปะตะดะฝะธะน ะฟะฐะบะตั
// ...
// ะฒะบะปััะฐะตะผ ัะฐะนะผะตั CloseWait โ ะดะปั ะพะถะธะดะฐะฝะธั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ัะพะตะดะธะฝะตะฝะธั ะธะปะธ ะตะณะพ ะทะฐะฒะตััะตะฝะธั
StartCloseWaitTimer(connectionRecord);
}
เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบฅเบตเปเบกเบเบปเปเบเปเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเบญเบญเบ.
ReliableUdpState.StartCloseWaitTimer:
protected void StartCloseWaitTimer(ReliableUdpConnectionRecord connectionRecord)
{
if (connectionRecord.CloseWaitTimer != null)
connectionRecord.CloseWaitTimer.Change(connectionRecord.LongTimerPeriod, -1);
else
connectionRecord.CloseWaitTimer = new Timer(DisposeByTimeout, connectionRecord, connectionRecord.LongTimerPeriod, -1);
}
เปเบฅเบเบฐเปเบงเบฅเบฒเบเบฒเบเปเบปเบเปเบงเบฅเบฒเบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบดเบเปเบกเปเบ 30 เบงเบดเบเบฒเบเบตเบเบฒเบกเบเปเบฒเปเบฅเบตเปเบกเบเบปเปเบ.
เบซเบผเบฑเบเบเบฒเบเปเบงเบฅเบฒเบชเบฑเปเบเป, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบขเบนเปเบเปเบฒเบเบเบนเปเบฎเบฑเบเบเปเปเปเบเบญเบตเบเปเบเบทเปเบญเบซเบเบถเปเบ, เบเบฒเบเบฎเปเบญเบเบเปเบเบทเบเบชเบปเปเบเบญเบตเบเปเบเบทเปเบญเบซเบเบถเปเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบ, เปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบฅเบตเปเบกเบเบปเปเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเปเบเบปเปเบฒ.
เปเบกเบทเปเบญเปเบเบทเปเบญเบเบเบฑเบเปเบงเบฅเบฒเบเบดเบเปเบ, เบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบฑเบเบซเบกเบปเบเบเบญเบเบเบฑเบเบเบถเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเบเบชเบญเบเบเบฐเบเบทเบเบเปเบญเบเบญเบญเบเบกเบฒ. เบเบนเปโเบชเบปเปเบโเบฅเบฒเบโเบเบฒเบโเบเบงเบฒเบกโเบฅเบปเปเบกโเปเบซเบผเบงโเบเบญเบโเบเบฒเบโเบเบฑเบโเบชเบปเปเบโเบเบฑเบโเบเปเบฒโเบฎเปเบญเบโเบชเบฐโเบซเบกเบฑเบโเบเบปเปเบโเบเป (เปเบเบดเปเบ UDP API เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป).
เบเปเบญเบเบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบฑเบเบเบถเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป:
public void Dispose()
{
try
{
System.Threading.Monitor.Enter(this.LockerReceive);
}
finally
{
Interlocked.Increment(ref this.IsDone);
if (WaitForPacketsTimer != null)
{
WaitForPacketsTimer.Dispose();
}
if (CloseWaitTimer != null)
{
CloseWaitTimer.Dispose();
}
byte[] stream;
Tcb.IncomingStreams.TryRemove(Key, out stream);
stream = null;
Tcb.OutcomingStreams.TryRemove(Key, out stream);
stream = null;
System.Threading.Monitor.Exit(this.LockerReceive);
}
}
เปเบฅเบดเบเปเบเบปเปเบฒเปเบเปเบเบฅเบฐเบซเบฑเบ. เบเบฒเบเบเบทเปเบเบเบนเบเบฒเบเปเบญเบเบเปเปเบกเบนเบ
เปเบเบโเบงเบฒเบโเบเบฒเบโเบเบทเปเบโเบเบนโเบเบฒเบโเบชเบปเปเบโเบเปเปโเบกเบนเบโเปเบโเบเปโเบฅเบฐโเบเบตโเบเบญเบโเบเบฒเบโเบชเบนเบโเปเบชเบ packetโ:
เบเบฑเปเบเบเบตเปเปเบเปเบชเบปเบเบเบฐเบเบฒเปเบฅเปเบงเปเบเบเบฒเบเบเบดเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒ, เปเบกเบทเปเบญเปเบงเบฅเบฒเปเบฎเบฑเบเบงเบฝเบเบซเบกเบปเบเปเบงเบฅเบฒ, เบเบนเปเบฎเบฑเบเบเบฐเบเบงเบเปเบเบดเปเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเบชเบนเบเปเบชเบ. เปเบเบเปเบฅเบฐเบเบตเบเบญเบเบเบฒเบเบชเบนเบเปเบชเบเปเบเบฑเบเปเบเบฑเบ, เบเบฑเบเบเบตเบฅเบฒเบเบเบทเปเบเบญเบเบเปเบฒเบเบงเบเบเบญเบเบเบตเปเบเปเปเปเบเปเปเบเบซเบฒเบเบนเปเบฎเบฑเบเบเบฐเบเบทเบเบฅเบงเบเบฅเบงเบก. เบเบปเบงเปเบฅเบเปเบซเบผเบปเปเบฒเบเบตเปเบเบทเบเปเบชเปเปเบเบปเปเบฒเปเบเปเบเบญเบฒเปเบฃ LostPackets เบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบชเบฐเปเบเบฒเบฐ, เปเบฅเบฐเบเบฒเบเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบเปเบกเปเบเบเบทเบเบชเบปเปเบเปเบ.
เบเบฒเบโเบชเบปเปเบโเบเปเบฒโเบฎเปเบญเบโเบชเบฐโเบซเบกเบฑเบโเปเบเบทเปเบญโเบชเบปเปเบโเบเบทเบโเบเบฒเบโเบซเบธเปเบกโเบซเปเป (เบชเบฐโเบเบฒโเบเบฐโเบเบฒเบโเบเบฐโเบเบญเบโ):
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
//...
if (!ReliableUdpStateTools.CheckForNoPacketLoss(connectionRecord, connectionRecord.IsLastPacketReceived != 0))
{
// ะตััั ะฟะพัะตััะฝะฝัะต ะฟะฐะบะตัั, ะพัััะปะฐะตะผ ะทะฐะฟัะพัั ะฝะฐ ะฝะธั
foreach (int seqNum in connectionRecord.LostPackets)
{
if (seqNum != 0)
{
ReliableUdpStateTools.SendAskForLostPacket(connectionRecord, seqNum);
}
}
// ...
}
}
เบเบนเปเบชเบปเปเบเบเบฐเบเบญเบกเบฎเบฑเบเบเปเบฒเบฎเปเบญเบเบเปเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบทเบเปเบฅเบฐเบชเบปเปเบเบเบธเบเบเบตเปเบเบฒเบเบซเบฒเบเปเบ. เบกเบฑเบเปเบเบฑเบเบกเบนเบเบเปเบฒเบเบตเปเบชเบฑเบเปเบเบเบงเปเบฒเปเบเปเบงเบฅเบฒเบเบตเปเบเบนเปเบชเบปเปเบเปเบเปเปเบฅเบตเปเบกเบเบฒเบเบเบฑเบเปเบงเบฅเบฒเปเบเปเบเบดเบเบเบญเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเปเบฅเบฐ, เปเบกเบทเปเบญเปเบเปเบฎเบฑเบเบเบฒเบเบฎเปเบญเบเบเป, เบกเบฑเบเบเบทเบเบเบฑเปเบเบเบทเบเปเบซเบกเป.
เบชเบปเปเบเปเบเบฑเบเปเบเบฑเบเบเบตเปเปเบชเบเปเบเบเบทเบเปเปเป (เบชเบฐเบเบฒเบเบฐเบเบฒเบเบชเบปเปเบเบฎเบญเบเบงเบฝเบ):
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
// ...
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
// ัะฑัะพั ัะฐะนะผะตัะฐ ะทะฐะบัััะธั ัะพะตะดะธะฝะตะฝะธั
if (connectionRecord.CloseWaitTimer != null)
connectionRecord.CloseWaitTimer.Change(-1, -1);
// ...
// ััะพ ะทะฐะฟัะพั ะฝะฐ ะฟะพะฒัะพัะฝัั ะฟะตัะตะดะฐัั โ ะพัะฟัะฐะฒะปัะตะผ ััะตะฑัะตะผัะน ะฟะฐะบะตั
else
ReliableUdpStateTools.SendPacket(connectionRecord, ReliableUdpStateTools.RetransmissionCreateUdpPayload(connectionRecord, header.PacketNumber));
}
เปเบเบฑเบเปเบเบฑเบเบเบตเปเบซเบผเบปเบเปเบซเบผ (เบเบธเบเบเบต 3 เปเบเปเบเบเบงเบฒเบ) เปเบกเปเบเปเบเปเบฎเบฑเบเปเบเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฒเปเบเบปเปเบฒ. เบเบฒเบเบเบงเบเบชเบญเบเปเบกเปเบเปเบฎเบฑเบเปเบเบทเปเบญเปเบเบดเปเบเบงเปเบฒเบเปเบญเบเบขเปเบฝเบกเบฎเบฑเบเปเบกเปเบเปเบเบฑเบกเปเบฅเบฐเบเบฒเบเบชเบปเปเบเบเปเปเบกเบนเบเบเบปเบเบเบฐเบเบดเบเบทเบเบเบทเปเบเบเบน.
เบเบฒเบโเบเบงเบโเบชเบญเบโเบเบฒเบ hits เปเบโเบเปเบญเบโเบขเปเบฝเบกโเบเบตเปโเปเบเปโเบฎเบฑเบ (เบชเบฐโเบเบฒโเบเบฐโเบเบฒเบโเบเบฐโเบเบญเบโ)โ:
public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
// ...
// ัะฒะตะปะธัะธะฒะฐะตะผ ััะตััะธะบ ะฟะฐะบะตัะพะฒ
connectionRecord.PacketCounter++;
// ะทะฐะฟะธััะฒะฐะตะผ ะฒ ะผะฐััะธะฒ ัะฟัะฐะฒะปะตะฝะธั ะพะบะฝะพะผ ัะตะบััะธะน ะฝะพะผะตั ะฟะฐะบะตัะฐ
connectionRecord.WindowControlArray[header.PacketNumber - connectionRecord.WindowLowerBound] = header.PacketNumber;
// ัััะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฝะฐะธะฑะพะปััะธะน ะฟัะธัะตะดัะธะน ะฟะฐะบะตั
if (header.PacketNumber > connectionRecord.RcvCurrent)
connectionRecord.RcvCurrent = header.PacketNumber;
// ะฟะตัะตะทะฐะฟััะบะฐะผ ัะฐะนะผะตัั
connectionRecord.TimerSecondTry = false;
connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
if (connectionRecord.CloseWaitTimer != null)
connectionRecord.CloseWaitTimer.Change(-1, -1);
// ...
// ะตัะปะธ ะฝะฐะผ ะฟัะธัะปะธ ะฒัะต ะฟะฐะบะตัั ะพะบะฝะฐ, ัะพ ัะฑัะฐััะฒะฐะตะผ ััะตััะธะบ
// ะธ ะฒัััะปะฐะตะผ ะฟะฐะบะตั ะฟะพะดัะฒะตัะถะดะตะฝะธะต
else if (connectionRecord.PacketCounter == connectionRecord.WindowSize)
{
// ัะฑัะฐััะฒะฐะตะผ ััะตััะธะบ.
connectionRecord.PacketCounter = 0;
// ัะดะฒะธะฝัะปะธ ะพะบะฝะพ ะฟะตัะตะดะฐัะธ
connectionRecord.WindowLowerBound += connectionRecord.WindowSize;
// ะพะฑะฝัะปะตะฝะธะต ะผะฐััะธะฒะฐ ัะฟัะฐะฒะปะตะฝะธั ะฟะตัะตะดะฐัะตะน
connectionRecord.WindowControlArray.Nullify();
ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
}
// ...
}
UDP API เบเบตเปเปเบเบทเปเบญเบเบทเปเบเป
เปเบเบทเปเบญเบเบปเบงเบเบฑเบเบเบฑเบเปเบเปเบเบเบญเบเบเบฒเบเปเบญเบเบเปเปเบกเบนเบ, เบกเบตเบซเปเบญเบเบฎเบฝเบ Udp Reliable เปเบเบตเบ, เปเบเบดเปเบเปเบกเปเบ wrapper เปเบเบดเบเบเบปเบงเบเบงเบเบเบธเบกเบเบฒเบเปเบญเบเบเปเบฒเบ. เบเบตเปเปเบกเปเบเบชเบฐเบกเบฒเบเบดเบเบเบตเปเบชเปเบฒเบเบฑเบเบเบตเปเบชเบธเบเบเบญเบเบซเปเบญเบเบฎเบฝเบ:
public sealed class ReliableUdp : IDisposable
{
// ะฟะพะปััะฐะตั ะปะพะบะฐะปัะฝัั ะบะพะฝะตัะฝัั ัะพัะบั
public IPEndPoint LocalEndpoint
// ัะพะทะดะฐะตั ัะบะทะตะผะฟะปัั ReliableUdp ะธ ะทะฐะฟััะบะฐะตั
// ะฟัะพัะปััะธะฒะฐะฝะธะต ะฒั
ะพะดััะธั
ะฟะฐะบะตัะพะฒ ะฝะฐ ัะบะฐะทะฐะฝะฝะพะผ IP ะฐะดัะตัะต
// ะธ ะฟะพััั. ะะฝะฐัะตะฝะธะต 0 ะดะปั ะฟะพััะฐ ะพะทะฝะฐัะฐะตั ะธัะฟะพะปัะทะพะฒะฐะฝะธะต
// ะดะธะฝะฐะผะธัะตัะบะธ ะฒัะดะตะปะตะฝะฝะพะณะพ ะฟะพััะฐ
public ReliableUdp(IPAddress localAddress, int port = 0)
// ะฟะพะดะฟะธัะบะฐ ะฝะฐ ะฟะพะปััะตะฝะธะต ะฒั
ะพะดััะธั
ัะพะพะฑัะตะฝะธะน
public ReliableUdpSubscribeObject SubscribeOnMessages(ReliableUdpMessageCallback callback, ReliableUdpMessageTypes messageType = ReliableUdpMessageTypes.Any, IPEndPoint ipEndPoint = null)
// ะพัะฟะธัะบะฐ ะพั ะฟะพะปััะตะฝะธั ัะพะพะฑัะตะฝะธะน
public void Unsubscribe(ReliableUdpSubscribeObject subscribeObject)
// ะฐัะธะฝั
ัะพะฝะฝะพ ะพัะฟัะฐะฒะธัั ัะพะพะฑัะตะฝะธะต
// ะัะธะผะตัะฐะฝะธะต: ัะพะฒะผะตััะธะผะพััั ั XP ะธ Server 2003 ะฝะต ัะตััะตััั, ั.ะบ. ะธัะฟะพะปัะทัะตััั .NET Framework 4.0
public Task<bool> SendMessageAsync(ReliableUdpMessage reliableUdpMessage, IPEndPoint remoteEndPoint, CancellationToken cToken)
// ะฝะฐัะฐัั ะฐัะธะฝั
ัะพะฝะฝัั ะพัะฟัะฐะฒะบั ัะพะพะฑัะตะฝะธั
public IAsyncResult BeginSendMessage(ReliableUdpMessage reliableUdpMessage, IPEndPoint remoteEndPoint, AsyncCallback asyncCallback, Object state)
// ะฟะพะปััะธัั ัะตะทัะปััะฐั ะฐัะธะฝั
ัะพะฝะฝะพะน ะพัะฟัะฐะฒะบะธ
public bool EndSendMessage(IAsyncResult asyncResult)
// ะพัะธััะธัั ัะตััััั
public void Dispose()
}
เบเปเปเบเบงเบฒเบกเปเบกเปเบเปเบเปเบฎเบฑเบเปเบเบเบเบฒเบเบชเบฐเบซเบกเบฑเบ. เบฅเบฒเบเปเบเบฑเบเบเบญเบเบเบนเปเปเบเบเบชเบณเบฅเบฑเบเบงเบดเบเบตเบเบฒเบเปเบเบเบฑเบ:
public delegate void ReliableUdpMessageCallback( ReliableUdpMessage reliableUdpMessage, IPEndPoint remoteClient );
เบเปเปเบเบงเบฒเบก:
public class ReliableUdpMessage
{
// ัะธะฟ ัะพะพะฑัะตะฝะธั, ะฟัะพััะพะต ะฟะตัะตัะธัะปะตะฝะธะต
public ReliableUdpMessageTypes Type { get; private set; }
// ะดะฐะฝะฝัะต ัะพะพะฑัะตะฝะธั
public byte[] Body { get; private set; }
// ะตัะปะธ ัััะฐะฝะพะฒะปะตะฝะพ ะฒ true โ ะผะตั
ะฐะฝะธะทะผ ะฟะพะดัะฒะตัะถะดะตะฝะธั ะดะพััะฐะฒะบะธ ะฑัะดะตั ะพัะบะปััะตะฝ
// ะดะปั ะฟะตัะตะดะฐัะธ ะบะพะฝะบัะตัะฝะพะณะพ ัะพะพะฑัะตะฝะธั
public bool NoAsk { get; private set; }
}
เปเบเบทเปเบญเบเบญเบเบเบฐเปเบเบเบเปเปเบเบงเบฒเบกเบชเบฐเปเบเบฒเบฐ เปเบฅเบฐ/เบซเบผเบทเบเบนเปเบชเบปเปเบเบชเบฐเปเบเบฒเบฐ, เบชเบญเบเบเบปเบงเบเปเบฒเบเบปเบเบเบฒเบเปเบฅเบทเบญเบเปเบกเปเบเบเบทเบเบเปเบฒเปเบเป: ReliableUdpMessageTypes messageType เปเบฅเบฐ IPEndPoint ipEndPoint.
เบเบฐเปเบเบเบเปเปเบเบงเบฒเบก:
public enum ReliableUdpMessageTypes : short
{
// ะัะฑะพะต
Any = 0,
// ะะฐะฟัะพั ะบ STUN server
StunRequest = 1,
// ะัะฒะตั ะพั STUN server
StunResponse = 2,
// ะะตัะตะดะฐัะฐ ัะฐะนะปะฐ
FileTransfer =3,
// ...
}
เบเปเปเบเบงเบฒเบกเบเบทเบเบชเบปเปเบเปเบเบ asynchronous; เบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบตเป, เปเบเปเบเบเบญเบเบเบฐเบเบดเบเบฑเบเบฎเบนเบเปเบเบเบเบฒเบเบเบฝเบเปเบเบฅเปเบเบฅเบก asynchronous:
public IAsyncResult BeginSendMessage(ReliableUdpMessage reliableUdpMessage, IPEndPoint remoteEndPoint, AsyncCallback asyncCallback, Object state)
เบเบปเบเปเบเปเบฎเบฑเบเบเบญเบเบเบฒเบเบชเบปเปเบเบเปเปเบเบงเบฒเบกเบเบฐเปเบเบฑเบเบเบงเบฒเบกเบเบดเบ - เบเปเบฒเบเปเปเบเบงเบฒเบกเบกเบฒเบฎเบญเบเบเบนเปเบฎเบฑเบเบขเปเบฒเบเบชเปเบฒเปเบฅเบฑเบเบเบปเบเปเบฅเบฐเบเบดเบ - เบเปเบฒเบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบทเบเบเบดเบเปเบเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒ:
public bool EndSendMessage(IAsyncResult asyncResult)
เบชเบฐเบซเบฅเบธเบ
เบซเบผเบฒเบเบเปเปเปเบเปเบเบทเบเบญเบฐเบเบดเบเบฒเบเปเบเบเบปเบเบเบงเบฒเบกเบเบตเป. เบเบปเบเปเบเบเบฒเบเบเบฑเบเบเบนเปเบเบฐเบเบนเป, เบเปเปเบเบปเบเปเบงเบฑเปเบเปเบฅเบฐเบเบฒเบเบเบฑเบเบเบฒเบเบเบงเบฒเบกเบเบดเบเบเบฒเบ, เบเบฒเบเบเบฐเบเบดเบเบฑเบเบงเบดเบเบตเบเบฒเบเบชเบปเปเบเบเปเปเบเบงเบฒเบก asynchronous. เปเบเปเบซเบผเบฑเบเบเบญเบเปเบเปเบเบเบญเบ, เบฅเบฒเบเบฅเบฐเบญเบฝเบเบเบญเบเปเบซเบเบเบปเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบธเบเปเบเปเบเปเบเบฑเบเปเบเบฑเบ, เบเบฒเบเบชเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป, เปเบฅเบฐเบเบฒเบเบเบฑเบเบเบฒเบเปเบงเบฅเบฒเบซเบกเบปเบเปเบงเบฅเบฒ, เบเบงเบเบเบฐเปเบเปเบเบชเปเบฒเบฅเบฑเบเบเปเบฒเบ.
เบชเบฐเบเบฑเบเบเบตเปเบชเบฐเปเบเบเปเบซเปเปเบซเบฑเบเบเบญเบเปเบเปเบเบเบญเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเบตเปเปเบเบทเปเบญเบเบทเปเบเปเปเบกเปเบเปเบเบเปเบฎเบเปเบฅเบฐเบกเบตเบเบงเบฒเบกเบเบทเบเบซเบเบธเปเบเบเบฝเบเบเปเบเบตเปเบเบฐเบเบญเบเบชเบฐเบซเบเบญเบเบเบงเบฒเบกเบเปเบญเบเบเบฒเบเบเบตเปเบเปเบฒเบเบปเบเปเบงเปเบเปเบญเบเบซเบเปเบฒเบเบตเป. เปเบเปเบเปเบญเบเบเปเบญเบเบเบฒเบเปเบเบตเปเบกเบงเปเบฒเบเบฒเบเบเบฐเบเบดเบเบฑเบเบเบตเปเปเบเปเบญเบฐเบเบดเบเบฒเบเบชเบฒเบกเบฒเบเบเบฑเบเบเบธเบเปเบเป. เบเบปเบงเบขเปเบฒเบ, เปเบเบทเปเบญเปเบเบตเปเบกเบเบฒเบเบชเบปเปเบเบเปเบฒเบเปเบฅเบฐเบเบฒเบเบเปเบฝเบเปเบเบเปเบฅเบเบฐเปเบงเบฅเบฒ timer, เบเบปเบเปเบเปเบเบฑเปเบ: เบเปเบญเบเบขเปเบฝเบกเปเบฅเบทเปเบญเบเปเบฅเบฐ RTT เบชเบฒเบกเบฒเบเบเบทเบเปเบเบตเปเบกเปเบเบปเปเบฒเปเบเปเบเปเบเบเบญเบ, เบกเบฑเบเบเบฑเบเปเบเบฑเบเบเบฐเปเบซเบเบเบเบตเปเบเบฐเบเบฐเบเบดเบเบฑเบเบเบปเบเปเบเบเบฒเบเบเปเบฒเบเบปเบ MTU เบฅเบฐเบซเบงเปเบฒเบเบเบฒเบเปเบเบทเปเบญเบกเบเปเป (เปเบเปเบเบฝเบเปเบเปเบเปเบฒเบเปเปเบเบงเบฒเบกเบเบฐเบซเบเบฒเบเปเบซเบเปเบเบทเบเบชเบปเปเบ) .
เบเปโเบเบญเบโเปเบโเบเปเบฒเบโเบชเปเบฒโเบฅเบฑเบโเบเบฒเบโเปเบญเบปเบฒโเปเบโเปเบชเปโเบเบญเบโเบเปเบฒเบโ, เบเปเบฒโเบเบฐโเปเบเบปเปเบฒโเบซเบงเบฑเบโเบงเปเบฒโเบเบฐโเบเปเบฒโเปเบซเบฑเบโเปเบฅเบฐโเบเปเบฒโเปเบซเบฑเบโเบเบญเบโเบเปเบฒเบโ.
PS เบชเปเบฒเบฅเบฑเบเบเบนเปเบเบตเปเบกเบตเบเบงเบฒเบกเบชเบปเบเปเบเปเบเบฅเบฒเบเบฅเบฐเบญเบฝเบเบซเบผเบทเบเบฝเบเปเบเปเบเปเบญเบเบเบฒเบเบเบตเปเบเบฐเบเบปเบเบชเบญเบเปเบเปเบเบเบญเบ, เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเบเปเบเบเบเบฒเบเปเบ GitHube:
เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบตเปเปเบเบฑเบเบเบฐเปเบซเบเบเปเบฅเบฐเบเบปเบเบเบงเบฒเบก
- เบเปเปเบเปเบฒเบเบปเบเบเบญเบเปเบเปเบเบเบญเบ TCP:
เปเบเบเบฒเบชเบฒเบญเบฑเบเบเบดเบ ะธเปเบเบเบฒเบชเบฒเบฅเบฑเบเปเบเบ - เบเปเปเบเปเบฒเบเบปเบเบเบญเบเปเบเปเบเบเบญเบ UDP:
เปเบเบเบฒเบชเบฒเบญเบฑเบเบเบดเบ ะธเปเบเบเบฒเบชเบฒเบฅเบฑเบเปเบเบ - เบเบฒเบเบชเบปเบเบเบฐเบเบฒเบเปเบฝเบงเบเบฑเบเบเบดเบเบตเบเบฒเบ RUDP:
draft-ietf-sigtran-reliable-udp-00 - เบญเบฐเบเบธเบชเบฑเบเบเบฒเบเปเปเบกเบนเบเบเบตเปเปเบเบทเปเบญเบเบทเปเบเป:
rfc908 ะธrfc1151 - เบเบฒเบเบเบฐเบเบดเบเบฑเบเบเปเบฒเบเบเบฒเบเบเบญเบเบเบฒเบเบขเบทเบเบขเบฑเบเบเบฒเบเบเบฑเบเบชเบปเปเบเบเปเบฒเบ UDP:
เบเบงเบเบเบธเบกเปเบเบทเบญเบเปเบฒเบเบเบฑเบเปเบปเบเบเบญเบเปเบเบปเปเบฒเบเปเบงเบ .NET เปเบฅเบฐ UDP - เบเบปเบเบเบงเบฒเบกเบญเบฐเบเบดเบเบฒเบเบเบปเบเปเบเบเบฒเบเบเปเบฒเบกเบเปเบฒเบ NAT:
เบเบฒเบโเบชเบทเปโเบชเบฒเบ Peer-to-Peer เบเบปเปเบงโเปเบเบทเบญโเบเปเบฒเบโเบเบนเปโเปเบโเบเบตเปโเบขเบนเปโ - เบเบฒเบเบเบฐเบเบดเบเบฑเบเบฎเบนเบเปเบเบเบเบฒเบเบเบฝเบเปเบเบฅเปเบเบฅเบก asynchronous:
เบเบฒเบเบเบฐเบเบดเบเบฑเบเบเบปเบงเปเบเบเบเบฒเบเบเบฝเบเปเบเบฅเปเบเบฅเบก Asynchronous CLR ะธเบงเบดเบเบตเบเบฒเบเบเบฐเบเบดเบเบฑเบเบฎเบนเบเปเบเบเบเบฒเบเบญเบญเบเปเบเบ IAsyncResult - เบเบฒเบ Porting the asynchronous programming model to the task-based asynchronous pattern (APM in TAP):
TPL เปเบฅเบฐเปเบเบเบเบฑเปเบเปเบเบตเบก .NET Asynchronous Programming
Interop เบเบฑเบเบฎเบนเบเปเบเบ Asynchronous เปเบฅเบฐเบเบฐเปเบเบเบญเบทเปเบเป
เบญเบฑเบเปเบเบ: เบเบญเบเปเบ
เปเบซเบผเปเบเบเปเปเบกเบนเบ: www.habr.com