.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಇಂಟರ್ನೆಟ್ ಬಹಳ ಹಿಂದೆಯೇ ಬದಲಾಗಿದೆ. ಇಂಟರ್ನೆಟ್‌ನ ಮುಖ್ಯ ಪ್ರೋಟೋಕಾಲ್‌ಗಳಲ್ಲಿ ಒಂದಾದ - ಯುಡಿಪಿಯು ಡೇಟಾಗ್ರಾಮ್‌ಗಳು ಮತ್ತು ಪ್ರಸಾರಗಳನ್ನು ತಲುಪಿಸಲು ಮಾತ್ರವಲ್ಲದೆ ನೆಟ್‌ವರ್ಕ್ ನೋಡ್‌ಗಳ ನಡುವೆ "ಪೀರ್-ಟು-ಪೀರ್" ಸಂಪರ್ಕಗಳನ್ನು ಒದಗಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಂದ ಬಳಸಲ್ಪಡುತ್ತದೆ. ಅದರ ಸರಳ ವಿನ್ಯಾಸದಿಂದಾಗಿ, ಈ ಪ್ರೋಟೋಕಾಲ್ ಹಿಂದೆ ಯೋಜಿತವಲ್ಲದ ಅನೇಕ ಬಳಕೆಗಳನ್ನು ಹೊಂದಿದೆ, ಆದಾಗ್ಯೂ, ಖಾತರಿಪಡಿಸಿದ ವಿತರಣೆಯ ಕೊರತೆಯಂತಹ ಪ್ರೋಟೋಕಾಲ್‌ನ ನ್ಯೂನತೆಗಳು ಎಲ್ಲಿಯೂ ಕಣ್ಮರೆಯಾಗಿಲ್ಲ. ಈ ಲೇಖನವು UDP ಯ ಮೇಲೆ ಖಾತರಿಪಡಿಸಿದ ವಿತರಣಾ ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನವನ್ನು ವಿವರಿಸುತ್ತದೆ.
ಪರಿವಿಡಿ:ಪ್ರವೇಶ
ಪ್ರೋಟೋಕಾಲ್ ಅಗತ್ಯತೆಗಳು
ವಿಶ್ವಾಸಾರ್ಹ UDP ಹೆಡರ್
ಪ್ರೋಟೋಕಾಲ್ನ ಸಾಮಾನ್ಯ ತತ್ವಗಳು
ಸಮಯಾವಧಿಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ ಟೈಮರ್‌ಗಳು
ವಿಶ್ವಾಸಾರ್ಹ UDP ಪ್ರಸರಣ ಸ್ಥಿತಿ ರೇಖಾಚಿತ್ರ
ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಪ್ರಸರಣ ನಿಯಂತ್ರಣ ಘಟಕ
ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ರಾಜ್ಯಗಳು

ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸುವುದು ಮತ್ತು ಸ್ಥಾಪಿಸುವುದು
ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಸಮಯ ಮೀರಿದಾಗ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಲಾಗುತ್ತಿದೆ
ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಡೇಟಾ ವರ್ಗಾವಣೆಯನ್ನು ಮರುಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ
ವಿಶ್ವಾಸಾರ್ಹ UDP API
ತೀರ್ಮಾನಕ್ಕೆ
ಉಪಯುಕ್ತ ಲಿಂಕ್‌ಗಳು ಮತ್ತು ಲೇಖನಗಳು

ಪ್ರವೇಶ

ಇಂಟರ್‌ನೆಟ್‌ನ ಮೂಲ ವಾಸ್ತುಶಿಲ್ಪವು ಏಕರೂಪದ ವಿಳಾಸ ಜಾಗವನ್ನು ಹೊಂದಿದ್ದು, ಇದರಲ್ಲಿ ಪ್ರತಿ ನೋಡ್ ಜಾಗತಿಕ ಮತ್ತು ವಿಶಿಷ್ಟವಾದ IP ವಿಳಾಸವನ್ನು ಹೊಂದಿತ್ತು ಮತ್ತು ಇತರ ನೋಡ್‌ಗಳೊಂದಿಗೆ ನೇರವಾಗಿ ಸಂವಹನ ನಡೆಸಬಹುದು. ಈಗ ಇಂಟರ್ನೆಟ್, ವಾಸ್ತವವಾಗಿ, ವಿಭಿನ್ನ ವಾಸ್ತುಶಿಲ್ಪವನ್ನು ಹೊಂದಿದೆ - ಜಾಗತಿಕ IP ವಿಳಾಸಗಳ ಒಂದು ಪ್ರದೇಶ ಮತ್ತು NAT ಸಾಧನಗಳ ಹಿಂದೆ ಖಾಸಗಿ ವಿಳಾಸಗಳನ್ನು ಹೊಂದಿರುವ ಅನೇಕ ಪ್ರದೇಶಗಳು.ಈ ಆರ್ಕಿಟೆಕ್ಚರ್‌ನಲ್ಲಿ, ಜಾಗತಿಕ ವಿಳಾಸ ಸ್ಥಳದಲ್ಲಿರುವ ಸಾಧನಗಳು ಮಾತ್ರ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿರುವ ಯಾರೊಂದಿಗೂ ಸುಲಭವಾಗಿ ಸಂವಹನ ನಡೆಸಬಹುದು ಏಕೆಂದರೆ ಅವುಗಳು ಅನನ್ಯವಾದ, ಜಾಗತಿಕವಾಗಿ ರೂಟ್ ಮಾಡಬಹುದಾದ IP ವಿಳಾಸವನ್ನು ಹೊಂದಿವೆ. ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿರುವ ನೋಡ್ ಅದೇ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿರುವ ಇತರ ನೋಡ್‌ಗಳಿಗೆ ಸಂಪರ್ಕಿಸಬಹುದು ಮತ್ತು ಜಾಗತಿಕ ವಿಳಾಸ ಜಾಗದಲ್ಲಿ ಇತರ ಪ್ರಸಿದ್ಧ ನೋಡ್‌ಗಳಿಗೆ ಸಹ ಸಂಪರ್ಕಿಸಬಹುದು. ನೆಟ್‌ವರ್ಕ್ ವಿಳಾಸ ಅನುವಾದ ಕಾರ್ಯವಿಧಾನದ ಕಾರಣದಿಂದಾಗಿ ಈ ಪರಸ್ಪರ ಕ್ರಿಯೆಯನ್ನು ಹೆಚ್ಚಾಗಿ ಸಾಧಿಸಲಾಗುತ್ತದೆ. ವೈ-ಫೈ ರೂಟರ್‌ಗಳಂತಹ NAT ಸಾಧನಗಳು ಹೊರಹೋಗುವ ಸಂಪರ್ಕಗಳಿಗಾಗಿ ವಿಶೇಷ ಅನುವಾದ ಟೇಬಲ್ ನಮೂದುಗಳನ್ನು ರಚಿಸುತ್ತವೆ ಮತ್ತು ಪ್ಯಾಕೆಟ್‌ಗಳಲ್ಲಿ IP ವಿಳಾಸಗಳು ಮತ್ತು ಪೋರ್ಟ್ ಸಂಖ್ಯೆಗಳನ್ನು ಮಾರ್ಪಡಿಸುತ್ತವೆ. ಇದು ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ನಿಂದ ಜಾಗತಿಕ ವಿಳಾಸ ಜಾಗದಲ್ಲಿ ಹೋಸ್ಟ್‌ಗಳಿಗೆ ಹೊರಹೋಗುವ ಸಂಪರ್ಕಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ. ಆದರೆ ಅದೇ ಸಮಯದಲ್ಲಿ, ಒಳಬರುವ ಸಂಪರ್ಕಗಳಿಗೆ ಪ್ರತ್ಯೇಕ ನಿಯಮಗಳನ್ನು ಹೊಂದಿಸದ ಹೊರತು NAT ಸಾಧನಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಎಲ್ಲಾ ಒಳಬರುವ ಸಂಚಾರವನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತವೆ.

ಕ್ಲೈಂಟ್-ಸರ್ವರ್ ಸಂವಹನಕ್ಕಾಗಿ ಇಂಟರ್ನೆಟ್‌ನ ಈ ಆರ್ಕಿಟೆಕ್ಚರ್ ಸಾಕಷ್ಟು ಸರಿಯಾಗಿದೆ, ಅಲ್ಲಿ ಗ್ರಾಹಕರು ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ಗಳಲ್ಲಿರಬಹುದು ಮತ್ತು ಸರ್ವರ್‌ಗಳು ಜಾಗತಿಕ ವಿಳಾಸವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಆದರೆ ಇದು ನಡುವೆ ಎರಡು ನೋಡ್‌ಗಳ ನೇರ ಸಂಪರ್ಕಕ್ಕೆ ತೊಂದರೆಗಳನ್ನು ಸೃಷ್ಟಿಸುತ್ತದೆ ವಿವಿಧ ಖಾಸಗಿ ಜಾಲಗಳು. ಧ್ವನಿ ಪ್ರಸರಣ (ಸ್ಕೈಪ್), ಕಂಪ್ಯೂಟರ್‌ಗೆ ರಿಮೋಟ್ ಪ್ರವೇಶವನ್ನು ಪಡೆಯುವುದು (ಟೀಮ್‌ವೀಯರ್) ಅಥವಾ ಆನ್‌ಲೈನ್ ಗೇಮಿಂಗ್‌ನಂತಹ ಪೀರ್-ಟು-ಪೀರ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎರಡು ನೋಡ್‌ಗಳ ನಡುವಿನ ನೇರ ಸಂಪರ್ಕವು ಮುಖ್ಯವಾಗಿದೆ.

ವಿಭಿನ್ನ ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ಗಳಲ್ಲಿನ ಸಾಧನಗಳ ನಡುವೆ ಪೀರ್-ಟು-ಪೀರ್ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಅತ್ಯಂತ ಪರಿಣಾಮಕಾರಿ ವಿಧಾನಗಳಲ್ಲಿ ಒಂದನ್ನು ರಂಧ್ರ ಪಂಚಿಂಗ್ ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ. ಯುಡಿಪಿ ಪ್ರೋಟೋಕಾಲ್ ಆಧಾರಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳೊಂದಿಗೆ ಈ ತಂತ್ರವನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ.

ಆದರೆ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಡೇಟಾದ ಖಾತರಿಯ ವಿತರಣೆಯ ಅಗತ್ಯವಿದ್ದರೆ, ಉದಾಹರಣೆಗೆ, ನೀವು ಕಂಪ್ಯೂಟರ್‌ಗಳ ನಡುವೆ ಫೈಲ್‌ಗಳನ್ನು ವರ್ಗಾಯಿಸಿದರೆ, ಯುಡಿಪಿಯು ಖಾತರಿಪಡಿಸಿದ ವಿತರಣಾ ಪ್ರೋಟೋಕಾಲ್ ಅಲ್ಲ ಮತ್ತು ಟಿಸಿಪಿಗಿಂತ ಭಿನ್ನವಾಗಿ ಪ್ಯಾಕೆಟ್ ವಿತರಣೆಯನ್ನು ಕ್ರಮವಾಗಿ ಒದಗಿಸದ ಕಾರಣ ಯುಡಿಪಿಯನ್ನು ಬಳಸುವುದರಿಂದ ಅನೇಕ ತೊಂದರೆಗಳು ಉಂಟಾಗುತ್ತವೆ. ಶಿಷ್ಟಾಚಾರ.

ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಖಾತರಿಪಡಿಸಿದ ಪ್ಯಾಕೆಟ್ ವಿತರಣೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು, ಯುಡಿಪಿಯ ಮೇಲೆ ಅಗತ್ಯ ಕಾರ್ಯಗಳನ್ನು ಮತ್ತು ಕೆಲಸಗಳನ್ನು ಒದಗಿಸುವ ಅಪ್ಲಿಕೇಶನ್ ಲೇಯರ್ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಅಗತ್ಯವಿದೆ.

ವಿಭಿನ್ನ ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ಗಳಲ್ಲಿ ನೋಡ್‌ಗಳ ನಡುವೆ TCP ಸಂಪರ್ಕಗಳನ್ನು ಸ್ಥಾಪಿಸಲು TCP ರಂಧ್ರ ಪಂಚಿಂಗ್ ತಂತ್ರವಿದೆ ಎಂದು ನಾನು ಈಗಿನಿಂದಲೇ ಗಮನಿಸಲು ಬಯಸುತ್ತೇನೆ, ಆದರೆ ಅನೇಕ NAT ಸಾಧನಗಳಿಂದ ಇದಕ್ಕೆ ಬೆಂಬಲದ ಕೊರತೆಯಿಂದಾಗಿ, ಇದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಸಂಪರ್ಕಿಸುವ ಮುಖ್ಯ ಮಾರ್ಗವೆಂದು ಪರಿಗಣಿಸಲಾಗುವುದಿಲ್ಲ. ಅಂತಹ ನೋಡ್ಗಳು.

ಈ ಲೇಖನದ ಉಳಿದ ಭಾಗಕ್ಕಾಗಿ, ನಾನು ಖಾತರಿಪಡಿಸಿದ ವಿತರಣಾ ಪ್ರೋಟೋಕಾಲ್ನ ಅನುಷ್ಠಾನದ ಮೇಲೆ ಮಾತ್ರ ಕೇಂದ್ರೀಕರಿಸುತ್ತೇನೆ. UDP ರಂಧ್ರ ಪಂಚಿಂಗ್ ತಂತ್ರದ ಅನುಷ್ಠಾನವನ್ನು ಮುಂದಿನ ಲೇಖನಗಳಲ್ಲಿ ವಿವರಿಸಲಾಗುವುದು.

ಪ್ರೋಟೋಕಾಲ್ ಅಗತ್ಯತೆಗಳು

  1. ಸಕಾರಾತ್ಮಕ ಪ್ರತಿಕ್ರಿಯೆ ಕಾರ್ಯವಿಧಾನದ ಮೂಲಕ ವಿಶ್ವಾಸಾರ್ಹ ಪ್ಯಾಕೆಟ್ ವಿತರಣೆಯನ್ನು ಅಳವಡಿಸಲಾಗಿದೆ (ಸಕಾರಾತ್ಮಕ ಸ್ವೀಕೃತಿ ಎಂದು ಕರೆಯಲ್ಪಡುವ)
  2. ದೊಡ್ಡ ಡೇಟಾದ ಸಮರ್ಥ ವರ್ಗಾವಣೆಯ ಅಗತ್ಯ, ಅಂದರೆ. ಪ್ರೋಟೋಕಾಲ್ ಅನಗತ್ಯ ಪ್ಯಾಕೆಟ್ ಪ್ರಸಾರವನ್ನು ತಪ್ಪಿಸಬೇಕು
  3. ವಿತರಣಾ ದೃಢೀಕರಣ ಕಾರ್ಯವಿಧಾನವನ್ನು ರದ್ದುಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗಬೇಕು ("ಶುದ್ಧ" UDP ಪ್ರೋಟೋಕಾಲ್ ಆಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಸಾಮರ್ಥ್ಯ)
  4. ಪ್ರತಿ ಸಂದೇಶದ ದೃಢೀಕರಣದೊಂದಿಗೆ ಕಮಾಂಡ್ ಮೋಡ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಸಾಮರ್ಥ್ಯ
  5. ಪ್ರೋಟೋಕಾಲ್ ಮೂಲಕ ಡೇಟಾ ವರ್ಗಾವಣೆಯ ಮೂಲ ಘಟಕವು ಸಂದೇಶವಾಗಿರಬೇಕು

ಈ ಅವಶ್ಯಕತೆಗಳು ಹೆಚ್ಚಾಗಿ ವಿವರಿಸಿದ ವಿಶ್ವಾಸಾರ್ಹ ಡೇಟಾ ಪ್ರೋಟೋಕಾಲ್ ಅವಶ್ಯಕತೆಗಳೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತವೆ ಆರ್‌ಎಫ್‌ಸಿ 908 и ಆರ್‌ಎಫ್‌ಸಿ 1151, ಮತ್ತು ಈ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸುವಾಗ ನಾನು ಆ ಮಾನದಂಡಗಳನ್ನು ಅವಲಂಬಿಸಿದೆ.

ಈ ಅವಶ್ಯಕತೆಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು, TCP ಮತ್ತು UDP ಪ್ರೋಟೋಕಾಲ್‌ಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಎರಡು ನೆಟ್‌ವರ್ಕ್ ನೋಡ್‌ಗಳ ನಡುವೆ ಡೇಟಾ ವರ್ಗಾವಣೆಯ ಸಮಯವನ್ನು ನೋಡೋಣ. ಎರಡೂ ಸಂದರ್ಭಗಳಲ್ಲಿ ನಾವು ಒಂದು ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತೇವೆ.
TCP ಮೂಲಕ ಸಂವಾದಾತ್ಮಕವಲ್ಲದ ಡೇಟಾದ ವರ್ಗಾವಣೆ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ರೇಖಾಚಿತ್ರದಿಂದ ನೀವು ನೋಡುವಂತೆ, ಪ್ಯಾಕೆಟ್ ನಷ್ಟದ ಸಂದರ್ಭದಲ್ಲಿ, TCP ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಪತ್ತೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ಕಳೆದುಹೋದ ವಿಭಾಗದ ಸಂಖ್ಯೆಯನ್ನು ಕೇಳುವ ಮೂಲಕ ಕಳುಹಿಸುವವರಿಗೆ ವರದಿ ಮಾಡುತ್ತದೆ.
UDP ಪ್ರೋಟೋಕಾಲ್ ಮೂಲಕ ಡೇಟಾ ವರ್ಗಾವಣೆ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

UDP ಯಾವುದೇ ನಷ್ಟ ಪತ್ತೆ ಕ್ರಮಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುವುದಿಲ್ಲ. UDP ಪ್ರೋಟೋಕಾಲ್‌ನಲ್ಲಿನ ಪ್ರಸರಣ ದೋಷಗಳ ನಿಯಂತ್ರಣವು ಸಂಪೂರ್ಣವಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ನ ಜವಾಬ್ದಾರಿಯಾಗಿದೆ.

TCP ಪ್ರೋಟೋಕಾಲ್‌ನಲ್ಲಿನ ದೋಷ ಪತ್ತೆಯನ್ನು ಅಂತಿಮ ನೋಡ್‌ನೊಂದಿಗೆ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ ಸಾಧಿಸಲಾಗುತ್ತದೆ, ಆ ಸಂಪರ್ಕದ ಸ್ಥಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸುವುದು, ಪ್ರತಿ ಪ್ಯಾಕೆಟ್ ಹೆಡರ್‌ನಲ್ಲಿ ಕಳುಹಿಸಲಾದ ಬೈಟ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಸೂಚಿಸುವುದು ಮತ್ತು ಸ್ವೀಕೃತಿ ಸಂಖ್ಯೆಯನ್ನು ಬಳಸಿಕೊಂಡು ರಶೀದಿಗಳನ್ನು ಸೂಚಿಸುವುದು.

ಹೆಚ್ಚುವರಿಯಾಗಿ, ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸುಧಾರಿಸಲು (ಅಂದರೆ ಸ್ವೀಕೃತಿಯನ್ನು ಸ್ವೀಕರಿಸದೆ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ವಿಭಾಗಗಳನ್ನು ಕಳುಹಿಸಿ), TCP ಪ್ರೋಟೋಕಾಲ್ ಪ್ರಸರಣ ವಿಂಡೋ ಎಂದು ಕರೆಯಲ್ಪಡುತ್ತದೆ - ವಿಭಾಗದ ಕಳುಹಿಸುವವರು ಸ್ವೀಕರಿಸಲು ನಿರೀಕ್ಷಿಸುವ ಡೇಟಾದ ಬೈಟ್‌ಗಳ ಸಂಖ್ಯೆ.

TCP ಪ್ರೋಟೋಕಾಲ್ ಕುರಿತು ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ, ನೋಡಿ ಆರ್‌ಎಫ್‌ಸಿ 793, UDP ಯಿಂದ ಆರ್‌ಎಫ್‌ಸಿ 768ಅಲ್ಲಿ, ವಾಸ್ತವವಾಗಿ, ಅವುಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ.

ಮೇಲಿನವುಗಳಿಂದ, UDP ಯ ಮೇಲೆ ವಿಶ್ವಾಸಾರ್ಹ ಸಂದೇಶ ವಿತರಣಾ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ರಚಿಸುವ ಸಲುವಾಗಿ (ಇನ್ನು ಮುಂದೆ ಹೀಗೆ ಉಲ್ಲೇಖಿಸಲಾಗಿದೆ ವಿಶ್ವಾಸಾರ್ಹ UDP), TCP ಯಂತೆಯೇ ಡೇಟಾ ವರ್ಗಾವಣೆ ಕಾರ್ಯವಿಧಾನಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಇದು ಅಗತ್ಯವಿದೆ. ಅವುಗಳೆಂದರೆ:

  • ಸಂಪರ್ಕ ಸ್ಥಿತಿಯನ್ನು ಉಳಿಸಿ
  • ವಿಭಾಗ ಸಂಖ್ಯೆಯನ್ನು ಬಳಸಿ
  • ವಿಶೇಷ ದೃಢೀಕರಣ ಪ್ಯಾಕೇಜುಗಳನ್ನು ಬಳಸಿ
  • ಪ್ರೋಟೋಕಾಲ್ ಥ್ರೋಪುಟ್ ಅನ್ನು ಹೆಚ್ಚಿಸಲು ಸರಳೀಕೃತ ವಿಂಡೊಯಿಂಗ್ ಕಾರ್ಯವಿಧಾನವನ್ನು ಬಳಸಿ

ಹೆಚ್ಚುವರಿಯಾಗಿ, ನಿಮಗೆ ಅಗತ್ಯವಿದೆ:

  • ಸಂಪರ್ಕಕ್ಕಾಗಿ ಸಂಪನ್ಮೂಲಗಳನ್ನು ನಿಯೋಜಿಸಲು ಸಂದೇಶದ ಪ್ರಾರಂಭವನ್ನು ಸೂಚಿಸಿ
  • ಸ್ವೀಕರಿಸಿದ ಸಂದೇಶವನ್ನು ಅಪ್‌ಸ್ಟ್ರೀಮ್ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ರವಾನಿಸಲು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಲು ಸಂದೇಶದ ಅಂತ್ಯವನ್ನು ಸೂಚಿಸಿ
  • "ಶುದ್ಧ" UDP ಯಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸಲು ವಿತರಣಾ ದೃಢೀಕರಣ ಕಾರ್ಯವಿಧಾನವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸಂಪರ್ಕ-ನಿರ್ದಿಷ್ಟ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಅನುಮತಿಸಿ

ವಿಶ್ವಾಸಾರ್ಹ UDP ಹೆಡರ್

ಯುಡಿಪಿ ಡೇಟಾಗ್ರಾಮ್ ಅನ್ನು ಐಪಿ ಡಾಟಾಗ್ರಾಮ್‌ನಲ್ಲಿ ಸುತ್ತುವರಿಯಲಾಗಿದೆ ಎಂದು ನೆನಪಿಸಿಕೊಳ್ಳಿ. ವಿಶ್ವಾಸಾರ್ಹ UDP ಪ್ಯಾಕೆಟ್ ಅನ್ನು UDP ಡೇಟಾಗ್ರಾಮ್‌ಗೆ ಸೂಕ್ತವಾಗಿ "ಸುತ್ತಿ" ಮಾಡಲಾಗಿದೆ.
ವಿಶ್ವಾಸಾರ್ಹ UDP ಹೆಡರ್ ಎನ್ಕ್ಯಾಪ್ಸುಲೇಶನ್:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ವಿಶ್ವಾಸಾರ್ಹ UDP ಹೆಡರ್ನ ರಚನೆಯು ತುಂಬಾ ಸರಳವಾಗಿದೆ:

.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

  • ಧ್ವಜಗಳು - ಪ್ಯಾಕೇಜ್ ನಿಯಂತ್ರಣ ಧ್ವಜಗಳು
  • MessageType - ನಿರ್ದಿಷ್ಟ ಸಂದೇಶಗಳಿಗೆ ಚಂದಾದಾರರಾಗಲು ಅಪ್‌ಸ್ಟ್ರೀಮ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಬಳಸುವ ಸಂದೇಶ ಪ್ರಕಾರ
  • TransmissionId - ಪ್ರಸರಣ ಸಂಖ್ಯೆ, ಜೊತೆಗೆ ಸ್ವೀಕರಿಸುವವರ ವಿಳಾಸ ಮತ್ತು ಪೋರ್ಟ್, ಸಂಪರ್ಕವನ್ನು ಅನನ್ಯವಾಗಿ ಗುರುತಿಸುತ್ತದೆ
  • ಪ್ಯಾಕೆಟ್ ಸಂಖ್ಯೆ - ಪ್ಯಾಕೆಟ್ ಸಂಖ್ಯೆ
  • ಆಯ್ಕೆಗಳು - ಹೆಚ್ಚುವರಿ ಪ್ರೋಟೋಕಾಲ್ ಆಯ್ಕೆಗಳು. ಮೊದಲ ಪ್ಯಾಕೆಟ್‌ನ ಸಂದರ್ಭದಲ್ಲಿ, ಸಂದೇಶದ ಗಾತ್ರವನ್ನು ಸೂಚಿಸಲು ಇದನ್ನು ಬಳಸಲಾಗುತ್ತದೆ

ಧ್ವಜಗಳು ಈ ಕೆಳಗಿನಂತಿವೆ:

  • ಮೊದಲ ಪ್ಯಾಕೆಟ್ - ಸಂದೇಶದ ಮೊದಲ ಪ್ಯಾಕೆಟ್
  • NoAsk - ಸಂದೇಶಕ್ಕೆ ಸ್ವೀಕೃತಿ ಕಾರ್ಯವಿಧಾನವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವ ಅಗತ್ಯವಿಲ್ಲ
  • LastPacket - ಸಂದೇಶದ ಕೊನೆಯ ಪ್ಯಾಕೆಟ್
  • RequestForPacket - ದೃಢೀಕರಣ ಪ್ಯಾಕೆಟ್ ಅಥವಾ ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್‌ಗಾಗಿ ವಿನಂತಿ

ಪ್ರೋಟೋಕಾಲ್ನ ಸಾಮಾನ್ಯ ತತ್ವಗಳು

ವಿಶ್ವಾಸಾರ್ಹ UDP ಎರಡು ನೋಡ್‌ಗಳ ನಡುವೆ ಖಾತರಿಯ ಸಂದೇಶ ರವಾನೆಯ ಮೇಲೆ ಕೇಂದ್ರೀಕೃತವಾಗಿರುವುದರಿಂದ, ಅದು ಇನ್ನೊಂದು ಬದಿಯೊಂದಿಗೆ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಶಕ್ತವಾಗಿರಬೇಕು. ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು, ಕಳುಹಿಸುವವರು ಫಸ್ಟ್‌ಪ್ಯಾಕೆಟ್ ಫ್ಲ್ಯಾಗ್‌ನೊಂದಿಗೆ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಕಳುಹಿಸುತ್ತಾರೆ, ಅದರ ಪ್ರತಿಕ್ರಿಯೆಯು ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿದೆ ಎಂದರ್ಥ. ಎಲ್ಲಾ ಪ್ರತಿಕ್ರಿಯೆ ಪ್ಯಾಕೆಟ್‌ಗಳು, ಅಥವಾ, ಬೇರೆ ರೀತಿಯಲ್ಲಿ ಹೇಳುವುದಾದರೆ, ಸ್ವೀಕೃತಿ ಪ್ಯಾಕೆಟ್‌ಗಳು, ಯಾವಾಗಲೂ ಪ್ಯಾಕೆಟ್‌ನಂಬರ್ ಕ್ಷೇತ್ರದ ಮೌಲ್ಯವನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಸ್ವೀಕರಿಸಿದ ಪ್ಯಾಕೆಟ್‌ಗಳ ದೊಡ್ಡ ಪ್ಯಾಕೆಟ್‌ನಂಬರ್ ಮೌಲ್ಯಕ್ಕಿಂತ ಒಂದಕ್ಕೆ ಹೊಂದಿಸಿ. ಕಳುಹಿಸಿದ ಮೊದಲ ಪ್ಯಾಕೆಟ್‌ನ ಆಯ್ಕೆಗಳ ಕ್ಷೇತ್ರವು ಸಂದೇಶದ ಗಾತ್ರವಾಗಿದೆ.

ಸಂಪರ್ಕವನ್ನು ಕೊನೆಗೊಳಿಸಲು ಇದೇ ರೀತಿಯ ಕಾರ್ಯವಿಧಾನವನ್ನು ಬಳಸಲಾಗುತ್ತದೆ. ಸಂದೇಶದ ಕೊನೆಯ ಪ್ಯಾಕೆಟ್‌ನಲ್ಲಿ LastPacket ಫ್ಲ್ಯಾಗ್ ಅನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ. ಪ್ರತಿಕ್ರಿಯೆ ಪ್ಯಾಕೆಟ್‌ನಲ್ಲಿ, ಕೊನೆಯ ಪ್ಯಾಕೆಟ್ + 1 ಸಂಖ್ಯೆಯನ್ನು ಸೂಚಿಸಲಾಗುತ್ತದೆ, ಸ್ವೀಕರಿಸುವ ಬದಿಗೆ ಸಂದೇಶದ ಯಶಸ್ವಿ ವಿತರಣೆ ಎಂದರ್ಥ.
ಸಂಪರ್ಕ ಸ್ಥಾಪನೆ ಮತ್ತು ಮುಕ್ತಾಯ ರೇಖಾಚಿತ್ರ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಿದಾಗ, ಡೇಟಾ ವರ್ಗಾವಣೆ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ಪ್ಯಾಕೆಟ್‌ಗಳ ಬ್ಲಾಕ್‌ಗಳಲ್ಲಿ ಡೇಟಾವನ್ನು ರವಾನಿಸಲಾಗುತ್ತದೆ. ಪ್ರತಿಯೊಂದು ಬ್ಲಾಕ್, ಕೊನೆಯದನ್ನು ಹೊರತುಪಡಿಸಿ, ನಿಗದಿತ ಸಂಖ್ಯೆಯ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಇದು ರಿಸೀವ್/ಟ್ರಾನ್ಸ್ಮಿಟ್ ವಿಂಡೋ ಗಾತ್ರಕ್ಕೆ ಸಮಾನವಾಗಿರುತ್ತದೆ. ಡೇಟಾದ ಕೊನೆಯ ಬ್ಲಾಕ್ ಕಡಿಮೆ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಹೊಂದಿರಬಹುದು. ಪ್ರತಿ ಬ್ಲಾಕ್ ಅನ್ನು ಕಳುಹಿಸಿದ ನಂತರ, ಕಳುಹಿಸುವ ಭಾಗವು ವಿತರಣಾ ದೃಢೀಕರಣಕ್ಕಾಗಿ ಅಥವಾ ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಮರು-ವಿತರಿಸುವ ವಿನಂತಿಗಾಗಿ ಕಾಯುತ್ತದೆ, ಪ್ರತಿಕ್ರಿಯೆಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಸ್ವೀಕರಿಸುವ/ರವಾನೆ ಮಾಡುವ ವಿಂಡೋವನ್ನು ತೆರೆದಿರುತ್ತದೆ. ಬ್ಲಾಕ್ ವಿತರಣೆಯ ದೃಢೀಕರಣವನ್ನು ಸ್ವೀಕರಿಸಿದ ನಂತರ, ಸ್ವೀಕರಿಸುವ/ರವಾನೆ ಮಾಡುವ ವಿಂಡೋ ಶಿಫ್ಟ್ ಆಗುತ್ತದೆ ಮತ್ತು ಡೇಟಾದ ಮುಂದಿನ ಬ್ಲಾಕ್ ಅನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತದೆ.

ಸ್ವೀಕರಿಸುವ ಭಾಗವು ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ. ಪ್ರತಿ ಪ್ಯಾಕೆಟ್ ಟ್ರಾನ್ಸ್ಮಿಷನ್ ವಿಂಡೋದಲ್ಲಿ ಬೀಳುತ್ತದೆಯೇ ಎಂದು ನೋಡಲು ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ. ಕಿಟಕಿಗೆ ಬೀಳದ ಪ್ಯಾಕೆಟ್‌ಗಳು ಮತ್ತು ನಕಲುಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಲಾಗುತ್ತದೆ. ಏಕೆಂದರೆ ವಿಂಡೋದ ಗಾತ್ರವು ಸ್ಥಿರವಾಗಿದ್ದರೆ ಮತ್ತು ಸ್ವೀಕರಿಸುವವರಿಗೆ ಮತ್ತು ಕಳುಹಿಸುವವರಿಗೆ ಒಂದೇ ಆಗಿದ್ದರೆ, ಪ್ಯಾಕೆಟ್‌ಗಳ ಬ್ಲಾಕ್ ಅನ್ನು ನಷ್ಟವಿಲ್ಲದೆ ತಲುಪಿಸಿದರೆ, ಮುಂದಿನ ಬ್ಲಾಕ್ ಡೇಟಾದ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ವಿಂಡೋವನ್ನು ಬದಲಾಯಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ವಿತರಣಾ ದೃಢೀಕರಣ ಕಳುಹಿಸಲಾಗಿದೆ. ಕೆಲಸದ ಟೈಮರ್ ನಿಗದಿಪಡಿಸಿದ ಅವಧಿಯೊಳಗೆ ವಿಂಡೋ ತುಂಬದಿದ್ದರೆ, ಯಾವ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ತಲುಪಿಸಲಾಗಿಲ್ಲ ಎಂಬುದರ ಕುರಿತು ಚೆಕ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಮರುವಿತರಣೆಗಾಗಿ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತದೆ.
ಮರುಪ್ರಸಾರ ರೇಖಾಚಿತ್ರ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಸಮಯಾವಧಿಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ ಟೈಮರ್‌ಗಳು

ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗದಿರಲು ಹಲವಾರು ಕಾರಣಗಳಿವೆ. ಉದಾಹರಣೆಗೆ, ಸ್ವೀಕರಿಸುವ ಪಕ್ಷವು ಆಫ್‌ಲೈನ್‌ನಲ್ಲಿದ್ದರೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಪ್ರಯತ್ನಿಸುವಾಗ, ಸಮಯ ಮೀರುವ ಮೂಲಕ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಲಾಗುತ್ತದೆ. ವಿಶ್ವಾಸಾರ್ಹ UDP ಅನುಷ್ಠಾನವು ಕಾಲಾವಧಿಯನ್ನು ಹೊಂದಿಸಲು ಎರಡು ಟೈಮರ್‌ಗಳನ್ನು ಬಳಸುತ್ತದೆ. ಮೊದಲನೆಯದು, ವರ್ಕಿಂಗ್ ಟೈಮರ್ ಅನ್ನು ರಿಮೋಟ್ ಹೋಸ್ಟ್‌ನಿಂದ ಪ್ರತಿಕ್ರಿಯೆಗಾಗಿ ಕಾಯಲು ಬಳಸಲಾಗುತ್ತದೆ. ಕಳುಹಿಸುವವರ ಬದಿಯಲ್ಲಿ ಅದು ಬೆಂಕಿಯಾದರೆ, ಕೊನೆಯದಾಗಿ ಕಳುಹಿಸಿದ ಪ್ಯಾಕೆಟ್ ಮರುಕಳಿಸಲ್ಪಡುತ್ತದೆ. ಸ್ವೀಕರಿಸುವವರ ಬಳಿ ಟೈಮರ್ ಅವಧಿ ಮುಗಿದರೆ, ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್‌ಗಳ ಪರಿಶೀಲನೆಯನ್ನು ನಡೆಸಲಾಗುತ್ತದೆ ಮತ್ತು ಮರುವಿತರಣೆಗಾಗಿ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತದೆ.

ನೋಡ್‌ಗಳ ನಡುವಿನ ಸಂವಹನದ ಕೊರತೆಯ ಸಂದರ್ಭದಲ್ಲಿ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಲು ಎರಡನೇ ಟೈಮರ್ ಅಗತ್ಯವಿದೆ. ಕಳುಹಿಸುವವರ ಬದಿಗೆ, ಕೆಲಸದ ಟೈಮರ್ ಅವಧಿ ಮುಗಿದ ತಕ್ಷಣ ಅದು ಪ್ರಾರಂಭವಾಗುತ್ತದೆ ಮತ್ತು ರಿಮೋಟ್ ನೋಡ್‌ನಿಂದ ಪ್ರತಿಕ್ರಿಯೆಗಾಗಿ ಕಾಯುತ್ತದೆ. ನಿಗದಿತ ಅವಧಿಯೊಳಗೆ ಯಾವುದೇ ಪ್ರತಿಕ್ರಿಯೆ ಇಲ್ಲದಿದ್ದರೆ, ಸಂಪರ್ಕವನ್ನು ಕೊನೆಗೊಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಲಾಗುತ್ತದೆ. ಸ್ವೀಕರಿಸುವ ಬದಿಗೆ, ಕೆಲಸದ ಟೈಮರ್ ಎರಡು ಬಾರಿ ಅವಧಿ ಮುಗಿದ ನಂತರ ಸಂಪರ್ಕದ ನಿಕಟ ಟೈಮರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ. ದೃಢೀಕರಣ ಪ್ಯಾಕೆಟ್ನ ನಷ್ಟದ ವಿರುದ್ಧ ವಿಮೆ ಮಾಡಲು ಇದು ಅವಶ್ಯಕವಾಗಿದೆ. ಟೈಮರ್ ಅವಧಿ ಮುಗಿದಾಗ, ಸಂಪರ್ಕವನ್ನು ಸಹ ಕೊನೆಗೊಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಲಾಗುತ್ತದೆ.

ವಿಶ್ವಾಸಾರ್ಹ UDP ಪ್ರಸರಣ ಸ್ಥಿತಿ ರೇಖಾಚಿತ್ರ

ಪ್ರೋಟೋಕಾಲ್ನ ತತ್ವಗಳನ್ನು ಸೀಮಿತ ಸ್ಥಿತಿಯ ಯಂತ್ರದಲ್ಲಿ ಅಳವಡಿಸಲಾಗಿದೆ, ಅದರ ಪ್ರತಿಯೊಂದು ಸ್ಥಿತಿಯು ಪ್ಯಾಕೆಟ್ ಸಂಸ್ಕರಣೆಯ ನಿರ್ದಿಷ್ಟ ತರ್ಕಕ್ಕೆ ಕಾರಣವಾಗಿದೆ.
ವಿಶ್ವಾಸಾರ್ಹ UDP ರಾಜ್ಯ ರೇಖಾಚಿತ್ರ:

.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಮುಚ್ಚಲಾಗಿದೆ - ಇದು ನಿಜವಾಗಿಯೂ ರಾಜ್ಯವಲ್ಲ, ಇದು ಆಟೋಮ್ಯಾಟನ್‌ಗೆ ಪ್ರಾರಂಭ ಮತ್ತು ಅಂತಿಮ ಹಂತವಾಗಿದೆ. ರಾಜ್ಯಕ್ಕಾಗಿ ಮುಚ್ಚಲಾಗಿದೆ ಟ್ರಾನ್ಸ್ಮಿಷನ್ ಕಂಟ್ರೋಲ್ ಬ್ಲಾಕ್ ಅನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ, ಇದು ಅಸಮಕಾಲಿಕ UDP ಸರ್ವರ್ ಅನ್ನು ಅಳವಡಿಸಿ, ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸೂಕ್ತ ಸಂಪರ್ಕಗಳಿಗೆ ಫಾರ್ವರ್ಡ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ರಾಜ್ಯ ಪ್ರಕ್ರಿಯೆಗೆ ಪ್ರಾರಂಭಿಸುತ್ತದೆ.

ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ - ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಿದಾಗ ಹೊರಹೋಗುವ ಸಂಪರ್ಕದ ಆರಂಭಿಕ ಸ್ಥಿತಿ.

ಈ ಸ್ಥಿತಿಯಲ್ಲಿ, ಸಾಮಾನ್ಯ ಸಂದೇಶಗಳಿಗಾಗಿ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತದೆ. ದೃಢೀಕರಣವನ್ನು ಕಳುಹಿಸದ ಸಂದೇಶಗಳಿಗೆ, ಸಂಪೂರ್ಣ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುವ ಏಕೈಕ ರಾಜ್ಯ ಇದು.

ಕಳುಹಿಸುವ ಸೈಕಲ್ - ಸಂದೇಶ ಪ್ಯಾಕೆಟ್‌ಗಳ ಪ್ರಸರಣಕ್ಕಾಗಿ ನೆಲದ ಸ್ಥಿತಿ.

ರಾಜ್ಯದಿಂದ ಅದಕ್ಕೆ ಪರಿವರ್ತನೆ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ ಸಂದೇಶದ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಕಳುಹಿಸಿದ ನಂತರ ಕೈಗೊಳ್ಳಲಾಗುತ್ತದೆ. ಈ ಸ್ಥಿತಿಯಲ್ಲಿಯೇ ಮರುಪ್ರಸಾರಕ್ಕಾಗಿ ಎಲ್ಲಾ ಸ್ವೀಕೃತಿಗಳು ಮತ್ತು ವಿನಂತಿಗಳು ಬರುತ್ತವೆ. ಅದರಿಂದ ನಿರ್ಗಮಿಸಲು ಎರಡು ಸಂದರ್ಭಗಳಲ್ಲಿ ಸಾಧ್ಯವಿದೆ - ಸಂದೇಶದ ಯಶಸ್ವಿ ವಿತರಣೆಯ ಸಂದರ್ಭದಲ್ಲಿ ಅಥವಾ ಸಮಯ ಮೀರಿದಾಗ.

ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಸ್ವೀಕರಿಸಲಾಗಿದೆ - ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸುವವರ ಆರಂಭಿಕ ಸ್ಥಿತಿ.

ಇದು ಪ್ರಸರಣದ ಆರಂಭದ ಸರಿಯಾಗಿರುವುದನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ, ಅಗತ್ಯ ರಚನೆಗಳನ್ನು ರಚಿಸುತ್ತದೆ ಮತ್ತು ಮೊದಲ ಪ್ಯಾಕೆಟ್ನ ಸ್ವೀಕೃತಿಯ ಸ್ವೀಕೃತಿಯನ್ನು ಕಳುಹಿಸುತ್ತದೆ.

ಒಂದೇ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಒಳಗೊಂಡಿರುವ ಮತ್ತು ವಿತರಣೆಯ ಪುರಾವೆಯನ್ನು ಬಳಸದೆ ಕಳುಹಿಸಲಾದ ಸಂದೇಶಕ್ಕಾಗಿ, ಇದು ಏಕೈಕ ರಾಜ್ಯವಾಗಿದೆ. ಅಂತಹ ಸಂದೇಶವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಿದ ನಂತರ, ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಲಾಗಿದೆ.

ಜೋಡಣೆ - ಸಂದೇಶ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮೂಲ ಸ್ಥಿತಿ.

ಇದು ತಾತ್ಕಾಲಿಕ ಸಂಗ್ರಹಣೆಗೆ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಬರೆಯುತ್ತದೆ, ಪ್ಯಾಕೆಟ್ ನಷ್ಟವನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ, ಪ್ಯಾಕೆಟ್‌ಗಳ ಬ್ಲಾಕ್ ಮತ್ತು ಸಂಪೂರ್ಣ ಸಂದೇಶದ ವಿತರಣೆಗಾಗಿ ಸ್ವೀಕೃತಿಗಳನ್ನು ಕಳುಹಿಸುತ್ತದೆ ಮತ್ತು ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್‌ಗಳ ಮರುವಿತರಣೆಗಾಗಿ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸುತ್ತದೆ. ಸಂಪೂರ್ಣ ಸಂದೇಶದ ಯಶಸ್ವಿ ಸ್ವೀಕೃತಿಯ ಸಂದರ್ಭದಲ್ಲಿ, ಸಂಪರ್ಕವು ರಾಜ್ಯಕ್ಕೆ ಹೋಗುತ್ತದೆ ಪೂರ್ಣಗೊಂಡಿದೆ, ಇಲ್ಲದಿದ್ದರೆ, ಅವಧಿ ಮೀರುತ್ತದೆ.

ಪೂರ್ಣಗೊಂಡಿದೆ - ಸಂಪೂರ್ಣ ಸಂದೇಶವನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಸ್ವೀಕರಿಸಿದ ಸಂದರ್ಭದಲ್ಲಿ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚುವುದು.

ಸಂದೇಶದ ಜೋಡಣೆಗೆ ಮತ್ತು ಸಂದೇಶದ ವಿತರಣಾ ದೃಢೀಕರಣವು ಕಳುಹಿಸುವವರಿಗೆ ದಾರಿಯಲ್ಲಿ ಕಳೆದುಹೋದ ಸಂದರ್ಭದಲ್ಲಿ ಈ ಸ್ಥಿತಿಯು ಅವಶ್ಯಕವಾಗಿದೆ. ಈ ಸ್ಥಿತಿಯು ಕಾಲಾವಧಿಯಿಂದ ನಿರ್ಗಮಿಸುತ್ತದೆ, ಆದರೆ ಸಂಪರ್ಕವನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಮುಚ್ಚಲಾಗಿದೆ ಎಂದು ಪರಿಗಣಿಸಲಾಗಿದೆ.

ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಪ್ರಸರಣ ನಿಯಂತ್ರಣ ಘಟಕ

ವಿಶ್ವಾಸಾರ್ಹ UDP ಯ ಪ್ರಮುಖ ಅಂಶಗಳಲ್ಲಿ ಒಂದು ಪ್ರಸರಣ ನಿಯಂತ್ರಣ ಬ್ಲಾಕ್ ಆಗಿದೆ. ಪ್ರಸ್ತುತ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಸಹಾಯಕ ಅಂಶಗಳನ್ನು ಸಂಗ್ರಹಿಸುವುದು, ಅನುಗುಣವಾದ ಸಂಪರ್ಕಗಳಿಗೆ ಒಳಬರುವ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ವಿತರಿಸುವುದು, ಸಂಪರ್ಕಕ್ಕೆ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಕಳುಹಿಸಲು ಇಂಟರ್ಫೇಸ್ ಅನ್ನು ಒದಗಿಸುವುದು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ API ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು ಈ ಬ್ಲಾಕ್‌ನ ಕಾರ್ಯವಾಗಿದೆ. ಪ್ರಸರಣ ನಿಯಂತ್ರಣ ಬ್ಲಾಕ್ ಯುಡಿಪಿ ಲೇಯರ್‌ನಿಂದ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಪಡೆಯುತ್ತದೆ ಮತ್ತು ಅವುಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗಾಗಿ ರಾಜ್ಯ ಯಂತ್ರಕ್ಕೆ ರವಾನಿಸುತ್ತದೆ. ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು, ಇದು ಅಸಮಕಾಲಿಕ UDP ಸರ್ವರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ.
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 ಸರ್ವರ್‌ನ ಅನುಷ್ಠಾನ:

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 ಪ್ರೋಟೋಕಾಲ್ನ ರಾಜ್ಯ ಯಂತ್ರವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತವೆ, ಅಲ್ಲಿ ಪ್ಯಾಕೆಟ್ಗಳ ಮುಖ್ಯ ಪ್ರಕ್ರಿಯೆಯು ನಡೆಯುತ್ತದೆ. ಅಮೂರ್ತ ವರ್ಗ ReliableUdpState ರಾಜ್ಯಕ್ಕೆ ಇಂಟರ್ಫೇಸ್ ಅನ್ನು ಒದಗಿಸುತ್ತದೆ:

.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಪ್ರೋಟೋಕಾಲ್‌ನ ಸಂಪೂರ್ಣ ತರ್ಕವನ್ನು ಮೇಲೆ ಪ್ರಸ್ತುತಪಡಿಸಿದ ವರ್ಗಗಳಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗುತ್ತದೆ, ಜೊತೆಗೆ ಸ್ಥಿರ ವಿಧಾನಗಳನ್ನು ಒದಗಿಸುವ ಸಹಾಯಕ ವರ್ಗದೊಂದಿಗೆ, ಉದಾಹರಣೆಗೆ, ಸಂಪರ್ಕ ದಾಖಲೆಯಿಂದ ReliableUdp ಹೆಡರ್ ಅನ್ನು ನಿರ್ಮಿಸುವುದು.

ಮುಂದೆ, ಪ್ರೋಟೋಕಾಲ್ನ ಮೂಲ ಕ್ರಮಾವಳಿಗಳನ್ನು ನಿರ್ಧರಿಸುವ ಇಂಟರ್ಫೇಸ್ ವಿಧಾನಗಳ ಅನುಷ್ಠಾನವನ್ನು ನಾವು ವಿವರವಾಗಿ ಪರಿಗಣಿಸುತ್ತೇವೆ.

ವಿಲೇವಾರಿ ಬೈಟೈಮ್ಔಟ್ ವಿಧಾನ

DisposeByTimeout ವಿಧಾನವು ಸಮಯ ಮೀರಿದ ನಂತರ ಸಂಪರ್ಕ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಲು ಮತ್ತು ಯಶಸ್ವಿ/ಅಸಫಲ ಸಂದೇಶ ವಿತರಣೆಯನ್ನು ಸಂಕೇತಿಸಲು ಕಾರಣವಾಗಿದೆ.
ReliableUdpState.DisposeByTimeout:

protected virtual void DisposeByTimeout(object record)
{
  ReliableUdpConnectionRecord connectionRecord = (ReliableUdpConnectionRecord) record;      
  if (record.AsyncResult != null)
  {
    connectionRecord.AsyncResult.SetAsCompleted(false);
  }
  connectionRecord.Dispose();
}

ರಾಜ್ಯದಲ್ಲಿ ಮಾತ್ರ ಅತಿಕ್ರಮಣವಾಗಿದೆ ಪೂರ್ಣಗೊಂಡಿದೆ.
ಪೂರ್ಣಗೊಂಡಿದೆ.ಟೈಮ್ಔಟ್ ಮೂಲಕ ವಿಲೇವಾರಿ:

protected override void DisposeByTimeout(object record)
{
  ReliableUdpConnectionRecord connectionRecord = (ReliableUdpConnectionRecord) record;
  // сообщаем об успешном получении сообщения
  SetAsCompleted(connectionRecord);        
}

ProcessPackets ವಿಧಾನ

ಪ್ರೊಸೆಸ್ಪ್ಯಾಕೆಟ್ಸ್ ವಿಧಾನವು ಪ್ಯಾಕೇಜ್ ಅಥವಾ ಪ್ಯಾಕೇಜುಗಳ ಹೆಚ್ಚುವರಿ ಪ್ರಕ್ರಿಯೆಗೆ ಕಾರಣವಾಗಿದೆ. ನೇರವಾಗಿ ಅಥವಾ ಪ್ಯಾಕೆಟ್ ವೇಯ್ಟ್ ಟೈಮರ್ ಮೂಲಕ ಕರೆ ಮಾಡಲಾಗಿದೆ.

ಸಮರ್ಥ ಜೋಡಣೆ ವಿಧಾನವನ್ನು ಅತಿಕ್ರಮಿಸಲಾಗಿದೆ ಮತ್ತು ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಮತ್ತು ರಾಜ್ಯಕ್ಕೆ ಪರಿವರ್ತನೆ ಮಾಡಲು ಕಾರಣವಾಗಿದೆ ಪೂರ್ಣಗೊಂಡಿದೆ, ಕೊನೆಯ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸ್ವೀಕರಿಸುವ ಮತ್ತು ಯಶಸ್ವಿ ಚೆಕ್ ಅನ್ನು ರವಾನಿಸುವ ಸಂದರ್ಭದಲ್ಲಿ
ಅಸೆಂಬ್ಲಿಂಗ್.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);
}

ಸ್ವೀಕರಿಸುವ ಪ್ಯಾಕೆಟ್ ವಿಧಾನ

ಸಮರ್ಥ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಸ್ವೀಕರಿಸಲಾಗಿದೆ ವಿಧಾನದ ಮುಖ್ಯ ಕಾರ್ಯವೆಂದರೆ ಮೊದಲ ಸಂದೇಶ ಪ್ಯಾಕೆಟ್ ನಿಜವಾಗಿಯೂ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಬಂದಿದೆಯೇ ಎಂದು ನಿರ್ಧರಿಸುವುದು ಮತ್ತು ಒಂದೇ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಒಳಗೊಂಡಿರುವ ಸಂದೇಶವನ್ನು ಸಂಗ್ರಹಿಸುವುದು.
ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಸ್ವೀಕರಿಸಲಾಗಿದೆ. ಸ್ವೀಕರಿಸಿ ಪ್ಯಾಕೆಟ್:

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);
  }
}

ಸಮರ್ಥ ಕಳುಹಿಸುವ ಸೈಕಲ್ ವಿತರಣಾ ಸ್ವೀಕೃತಿಗಳು ಮತ್ತು ಮರುಪ್ರಸಾರ ವಿನಂತಿಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಈ ವಿಧಾನವನ್ನು ಅತಿಕ್ರಮಿಸಲಾಗಿದೆ.
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));
}

ಸಮರ್ಥ ಜೋಡಣೆ ರಿಸೀವ್ ಪ್ಯಾಕೆಟ್ ವಿಧಾನದಲ್ಲಿ, ಒಳಬರುವ ಪ್ಯಾಕೆಟ್‌ಗಳಿಂದ ಸಂದೇಶವನ್ನು ಜೋಡಿಸುವ ಮುಖ್ಯ ಕೆಲಸ ನಡೆಯುತ್ತದೆ.
ಅಸೆಂಬ್ಲಿಂಗ್. ರಿಸೀವ್ ಪ್ಯಾಕೆಟ್:

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);
  }
}

ಸಮರ್ಥ ಪೂರ್ಣಗೊಂಡಿದೆ ಸಂದೇಶದ ಯಶಸ್ವಿ ವಿತರಣೆಯ ಮರು-ಸ್ವೀಕಾರವನ್ನು ಕಳುಹಿಸುವುದು ವಿಧಾನದ ಏಕೈಕ ಕಾರ್ಯವಾಗಿದೆ.
ಪೂರ್ಣಗೊಂಡಿದೆ. ಸ್ವೀಕರಿಸುವ ಪ್ಯಾಕೆಟ್:

public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
  // повторная отправка последнего пакета в связи с тем,
  // что последний ack не дошел до отправителя
  if (header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
  {
    ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
  }
}

ಪ್ಯಾಕೆಟ್ ವಿಧಾನವನ್ನು ಕಳುಹಿಸಿ

ಸಮರ್ಥ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ ಈ ವಿಧಾನವು ಡೇಟಾದ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಕಳುಹಿಸುತ್ತದೆ, ಅಥವಾ, ಸಂದೇಶಕ್ಕೆ ವಿತರಣಾ ದೃಢೀಕರಣದ ಅಗತ್ಯವಿಲ್ಲದಿದ್ದರೆ, ಸಂಪೂರ್ಣ ಸಂದೇಶ.
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 );
  }
}

ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸುವುದು ಮತ್ತು ಸ್ಥಾಪಿಸುವುದು

ಈಗ ನಾವು ಮೂಲಭೂತ ಸ್ಥಿತಿಗಳನ್ನು ಮತ್ತು ರಾಜ್ಯಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಬಳಸುವ ವಿಧಾನಗಳನ್ನು ನೋಡಿದ್ದೇವೆ, ಪ್ರೋಟೋಕಾಲ್ ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂಬುದರ ಕೆಲವು ಉದಾಹರಣೆಗಳನ್ನು ಸ್ವಲ್ಪ ಹೆಚ್ಚು ವಿವರವಾಗಿ ವಿಭಜಿಸೋಣ.
ಸಾಮಾನ್ಯ ಪರಿಸ್ಥಿತಿಗಳಲ್ಲಿ ಡೇಟಾ ಪ್ರಸರಣ ರೇಖಾಚಿತ್ರ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಸೃಷ್ಟಿಯನ್ನು ವಿವರವಾಗಿ ಪರಿಗಣಿಸಿ ಸಂಪರ್ಕ ದಾಖಲೆ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಲು ಮತ್ತು ಕಳುಹಿಸಲು. ಕಳುಹಿಸುವ ಸಂದೇಶ API ಅನ್ನು ಕರೆಯುವ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ವರ್ಗಾವಣೆಯನ್ನು ಯಾವಾಗಲೂ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ. ಮುಂದೆ, ಟ್ರಾನ್ಸ್ಮಿಷನ್ ಕಂಟ್ರೋಲ್ ಬ್ಲಾಕ್ನ ಸ್ಟಾರ್ಟ್ಟ್ರಾನ್ಸ್ಮಿಷನ್ ವಿಧಾನವನ್ನು ಆಹ್ವಾನಿಸಲಾಗುತ್ತದೆ, ಇದು ಹೊಸ ಸಂದೇಶಕ್ಕಾಗಿ ಡೇಟಾದ ಪ್ರಸರಣವನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ.
ಹೊರಹೋಗುವ ಸಂಪರ್ಕವನ್ನು ರಚಿಸುವುದು:

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 ಸ್ಥಿತಿ):

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);
}

ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಕಳುಹಿಸಿದ ನಂತರ, ಕಳುಹಿಸುವವರು ರಾಜ್ಯವನ್ನು ಪ್ರವೇಶಿಸುತ್ತಾರೆ ಕಳುಹಿಸುವ ಸೈಕಲ್ - ಪ್ಯಾಕೇಜ್ ವಿತರಣೆಯ ದೃಢೀಕರಣಕ್ಕಾಗಿ ನಿರೀಕ್ಷಿಸಿ.
ಸ್ವೀಕರಿಸುವ ಭಾಗವು ಎಂಡ್ ರಿಸೀವ್ ವಿಧಾನವನ್ನು ಬಳಸಿಕೊಂಡು ಕಳುಹಿಸಿದ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ, ಹೊಸದನ್ನು ರಚಿಸುತ್ತದೆ ಸಂಪರ್ಕ ದಾಖಲೆ ಮತ್ತು ಪೂರ್ವ ಪಾರ್ಸ್ ಮಾಡಿದ ಹೆಡರ್‌ನೊಂದಿಗೆ ಈ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗಾಗಿ ರಾಜ್ಯದ ರಿಸೀವ್ ಪ್ಯಾಕೆಟ್ ವಿಧಾನಕ್ಕೆ ರವಾನಿಸುತ್ತದೆ ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಸ್ವೀಕರಿಸಲಾಗಿದೆ
ಸ್ವೀಕರಿಸುವ ಬದಿಯಲ್ಲಿ ಸಂಪರ್ಕವನ್ನು ರಚಿಸುವುದು:

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);
}

ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸ್ವೀಕರಿಸುವುದು ಮತ್ತು ಸ್ವೀಕೃತಿಯನ್ನು ಕಳುಹಿಸುವುದು (ಮೊದಲ ಪ್ಯಾಕೆಟ್ ಸ್ವೀಕರಿಸಿದ ಸ್ಥಿತಿ):

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 ಯ ಪ್ರಮುಖ ಭಾಗವಾಗಿದೆ. ಮಧ್ಯಂತರ ನೋಡ್ ವಿಫಲವಾದ ಮತ್ತು ಎರಡೂ ದಿಕ್ಕುಗಳಲ್ಲಿ ಡೇಟಾ ವಿತರಣೆ ಅಸಾಧ್ಯವಾದ ಉದಾಹರಣೆಯನ್ನು ಪರಿಗಣಿಸಿ.
ಸಮಯ ಮೀರಿದ ಮೂಲಕ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚುವ ರೇಖಾಚಿತ್ರ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ರೇಖಾಚಿತ್ರದಿಂದ ನೋಡಬಹುದಾದಂತೆ, ಪ್ಯಾಕೆಟ್‌ಗಳ ಬ್ಲಾಕ್ ಅನ್ನು ಕಳುಹಿಸಿದ ನಂತರ ಕಳುಹಿಸುವವರ ಕೆಲಸದ ಟೈಮರ್ ತಕ್ಷಣವೇ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ಇದು ರಾಜ್ಯದ SendPacket ವಿಧಾನದಲ್ಲಿ ಸಂಭವಿಸುತ್ತದೆ ಕಳುಹಿಸುವ ಸೈಕಲ್.
ಕೆಲಸದ ಟೈಮರ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತಿದೆ (ಕಳುಹಿಸುವ ಸೈಕಲ್ ಸ್ಥಿತಿ):

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 ಸೆಕೆಂಡುಗಳಿಗೆ ಹೊಂದಿಸಲಾಗಿದೆ.

ಒಳಬರುವ ಸಂಪರ್ಕಕ್ಕಾಗಿ, ಕೊನೆಯ ಒಳಬರುವ ಡೇಟಾ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸ್ವೀಕರಿಸಿದ ನಂತರ ಟೈಮರ್ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ, ಇದು ರಾಜ್ಯದ ರಿಸೀವ್ ಪ್ಯಾಕೆಟ್ ವಿಧಾನದಲ್ಲಿ ಸಂಭವಿಸುತ್ತದೆ ಜೋಡಣೆ
ಕೆಲಸದ ಟೈಮರ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತಿದೆ (ಅಸೆಂಬಲ್ ಮಾಡುವ ಸ್ಥಿತಿ):

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);
  }
}

ಕೋಡ್‌ನಲ್ಲಿ ಆಳವಾಗಿ. ಡೇಟಾ ವರ್ಗಾವಣೆಯನ್ನು ಮರುಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ

ಪ್ಯಾಕೆಟ್ ನಷ್ಟದ ಸಂದರ್ಭದಲ್ಲಿ ಡೇಟಾ ಟ್ರಾನ್ಸ್ಮಿಷನ್ ರಿಕವರಿ ರೇಖಾಚಿತ್ರ:.Net ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ Udp ಪ್ರೋಟೋಕಾಲ್‌ನ ಅನುಷ್ಠಾನ

ಸಮಯ ಮೀರಿದ ಮೇಲೆ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚುವಲ್ಲಿ ಈಗಾಗಲೇ ಚರ್ಚಿಸಿದಂತೆ, ಕೆಲಸದ ಟೈಮರ್ ಅವಧಿ ಮುಗಿದಾಗ, ರಿಸೀವರ್ ಕಳೆದುಹೋದ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ. ಪ್ಯಾಕೆಟ್ ನಷ್ಟದ ಸಂದರ್ಭದಲ್ಲಿ, ಸ್ವೀಕರಿಸುವವರನ್ನು ತಲುಪದ ಪ್ಯಾಕೆಟ್‌ಗಳ ಸಂಖ್ಯೆಯ ಪಟ್ಟಿಯನ್ನು ಕಂಪೈಲ್ ಮಾಡಲಾಗುತ್ತದೆ. ಈ ಸಂಖ್ಯೆಗಳನ್ನು ನಿರ್ದಿಷ್ಟ ಸಂಪರ್ಕದ 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) ಒಳಬರುವ ಸಂಪರ್ಕದಿಂದ ಸ್ವೀಕರಿಸಲ್ಪಟ್ಟಿದೆ. ಸ್ವೀಕರಿಸುವ ವಿಂಡೋ ತುಂಬಿದೆಯೇ ಮತ್ತು ಸಾಮಾನ್ಯ ಡೇಟಾ ಪ್ರಸರಣವನ್ನು ಮರುಸ್ಥಾಪಿಸಲಾಗಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಲು ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ.
ಸ್ವೀಕರಿಸುವ ವಿಂಡೋದಲ್ಲಿ ಹಿಟ್‌ಗಳಿಗಾಗಿ ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ (ಜೋಡಣೆ ಸ್ಥಿತಿ):

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 ವರ್ಗವಿದೆ, ಇದು ವರ್ಗಾವಣೆ ನಿಯಂತ್ರಣ ಬ್ಲಾಕ್‌ನ ಮೇಲೆ ಹೊದಿಕೆಯಾಗಿದೆ. ವರ್ಗದ ಪ್ರಮುಖ ಸದಸ್ಯರು ಇಲ್ಲಿವೆ:

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,
  // ...
}

ಸಂದೇಶವನ್ನು ಅಸಮಕಾಲಿಕವಾಗಿ ಕಳುಹಿಸಲಾಗಿದೆ; ಇದಕ್ಕಾಗಿ, ಪ್ರೋಟೋಕಾಲ್ ಅಸಮಕಾಲಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮಾದರಿಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ:

public IAsyncResult BeginSendMessage(ReliableUdpMessage reliableUdpMessage, IPEndPoint remoteEndPoint, AsyncCallback asyncCallback, Object state)

ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುವ ಫಲಿತಾಂಶವು ನಿಜವಾಗಿರುತ್ತದೆ - ಸಂದೇಶವು ಸ್ವೀಕರಿಸುವವರಿಗೆ ಯಶಸ್ವಿಯಾಗಿ ತಲುಪಿದರೆ ಮತ್ತು ತಪ್ಪಾಗಿದ್ದರೆ - ಸಮಯ ಮೀರುವ ಮೂಲಕ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಿದ್ದರೆ:

public bool EndSendMessage(IAsyncResult asyncResult)

ತೀರ್ಮಾನಕ್ಕೆ

ಈ ಲೇಖನದಲ್ಲಿ ಹೆಚ್ಚಿನದನ್ನು ವಿವರಿಸಲಾಗಿಲ್ಲ. ಥ್ರೆಡ್ ಹೊಂದಾಣಿಕೆಯ ಕಾರ್ಯವಿಧಾನಗಳು, ವಿನಾಯಿತಿ ಮತ್ತು ದೋಷ ನಿರ್ವಹಣೆ, ಅಸಮಕಾಲಿಕ ಸಂದೇಶ ಕಳುಹಿಸುವ ವಿಧಾನಗಳ ಅನುಷ್ಠಾನ. ಆದರೆ ಪ್ರೋಟೋಕಾಲ್‌ನ ತಿರುಳು, ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು, ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಮತ್ತು ಸಮಯ ಮೀರುವಿಕೆಗಳನ್ನು ನಿರ್ವಹಿಸಲು ತರ್ಕದ ವಿವರಣೆಯು ನಿಮಗೆ ಸ್ಪಷ್ಟವಾಗಿರಬೇಕು.

ವಿಶ್ವಾಸಾರ್ಹ ವಿತರಣಾ ಪ್ರೋಟೋಕಾಲ್‌ನ ಪ್ರದರ್ಶಿತ ಆವೃತ್ತಿಯು ಹಿಂದೆ ವ್ಯಾಖ್ಯಾನಿಸಲಾದ ಅವಶ್ಯಕತೆಗಳನ್ನು ಪೂರೈಸಲು ಸಾಕಷ್ಟು ದೃಢವಾಗಿದೆ ಮತ್ತು ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ. ಆದರೆ ವಿವರಿಸಿದ ಅನುಷ್ಠಾನವನ್ನು ಸುಧಾರಿಸಬಹುದು ಎಂದು ನಾನು ಸೇರಿಸಲು ಬಯಸುತ್ತೇನೆ. ಉದಾಹರಣೆಗೆ, ಥ್ರೋಪುಟ್ ಅನ್ನು ಹೆಚ್ಚಿಸಲು ಮತ್ತು ಟೈಮರ್ ಅವಧಿಗಳನ್ನು ಕ್ರಿಯಾತ್ಮಕವಾಗಿ ಬದಲಾಯಿಸಲು, ಸ್ಲೈಡಿಂಗ್ ವಿಂಡೋ ಮತ್ತು RTT ಯಂತಹ ಕಾರ್ಯವಿಧಾನಗಳನ್ನು ಪ್ರೋಟೋಕಾಲ್‌ಗೆ ಸೇರಿಸಬಹುದು, ಸಂಪರ್ಕ ನೋಡ್‌ಗಳ ನಡುವೆ MTU ಅನ್ನು ನಿರ್ಧರಿಸುವ ಕಾರ್ಯವಿಧಾನವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಸಹ ಇದು ಉಪಯುಕ್ತವಾಗಿರುತ್ತದೆ (ಆದರೆ ದೊಡ್ಡ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಿದರೆ ಮಾತ್ರ) .

ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಧನ್ಯವಾದಗಳು, ನಿಮ್ಮ ಕಾಮೆಂಟ್‌ಗಳು ಮತ್ತು ಕಾಮೆಂಟ್‌ಗಳಿಗಾಗಿ ನಾನು ಎದುರು ನೋಡುತ್ತಿದ್ದೇನೆ.

PS ವಿವರಗಳಲ್ಲಿ ಆಸಕ್ತಿ ಹೊಂದಿರುವವರಿಗೆ ಅಥವಾ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಪರೀಕ್ಷಿಸಲು ಬಯಸುವವರಿಗೆ, GitHube ನಲ್ಲಿ ಯೋಜನೆಗೆ ಲಿಂಕ್:
ವಿಶ್ವಾಸಾರ್ಹ UDP ಯೋಜನೆ

ಉಪಯುಕ್ತ ಲಿಂಕ್‌ಗಳು ಮತ್ತು ಲೇಖನಗಳು

  1. TCP ಪ್ರೋಟೋಕಾಲ್ ವಿವರಣೆ: ಇಂಗ್ಲಿಷ್ನಲ್ಲಿ и ರಷ್ಯನ್ ಭಾಷೆಯಲ್ಲಿ
  2. UDP ಪ್ರೋಟೋಕಾಲ್ ವಿವರಣೆ: ಇಂಗ್ಲಿಷ್ನಲ್ಲಿ и ರಷ್ಯನ್ ಭಾಷೆಯಲ್ಲಿ
  3. RUDP ಪ್ರೋಟೋಕಾಲ್‌ನ ಚರ್ಚೆ: draft-ietf-sigtran-reliable-udp-00
  4. ವಿಶ್ವಾಸಾರ್ಹ ಡೇಟಾ ಪ್ರೋಟೋಕಾಲ್: ಆರ್‌ಎಫ್‌ಸಿ 908 и ಆರ್‌ಎಫ್‌ಸಿ 1151
  5. UDP ಮೂಲಕ ವಿತರಣಾ ದೃಢೀಕರಣದ ಸರಳ ಅನುಷ್ಠಾನ: .NET ಮತ್ತು UDP ಯೊಂದಿಗೆ ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕಿಂಗ್‌ನ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ತೆಗೆದುಕೊಳ್ಳಿ
  6. NAT ಟ್ರಾವರ್ಸಲ್ ಕಾರ್ಯವಿಧಾನಗಳನ್ನು ವಿವರಿಸುವ ಲೇಖನ: ನೆಟ್‌ವರ್ಕ್ ವಿಳಾಸ ಅನುವಾದಕರಾದ್ಯಂತ ಪೀರ್-ಟು-ಪೀರ್ ಸಂವಹನ
  7. ಅಸಮಕಾಲಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮಾದರಿಯ ಅನುಷ್ಠಾನ: CLR ಅಸಮಕಾಲಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮಾದರಿಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು и IAsyncResult ವಿನ್ಯಾಸ ಮಾದರಿಯನ್ನು ಹೇಗೆ ಕಾರ್ಯಗತಗೊಳಿಸುವುದು
  8. ಅಸಮಕಾಲಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮಾದರಿಯನ್ನು ಕಾರ್ಯ-ಆಧಾರಿತ ಅಸಮಕಾಲಿಕ ಮಾದರಿಗೆ ಪೋರ್ಟ್ ಮಾಡುವುದು (TAP ನಲ್ಲಿ APM):
    TPL ಮತ್ತು ಸಾಂಪ್ರದಾಯಿಕ .NET ಅಸಮಕಾಲಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್
    ಇತರ ಅಸಮಕಾಲಿಕ ಮಾದರಿಗಳು ಮತ್ತು ಪ್ರಕಾರಗಳೊಂದಿಗೆ ಇಂಟರ್ಯಾಪ್ ಮಾಡಿ

ನವೀಕರಿಸಿ: ಧನ್ಯವಾದಗಳು ಮೇಯೊರೊವ್ಪಿ и ಸಿದ್ರಿಸ್ತಿಜ್ ಇಂಟರ್ಫೇಸ್ಗೆ ಕಾರ್ಯವನ್ನು ಸೇರಿಸುವ ಕಲ್ಪನೆಗಾಗಿ. ಹಳೆಯ ಆಪರೇಟಿಂಗ್ ಸಿಸ್ಟಮ್‌ಗಳೊಂದಿಗೆ ಲೈಬ್ರರಿಯ ಹೊಂದಾಣಿಕೆಯನ್ನು ಉಲ್ಲಂಘಿಸಲಾಗಿಲ್ಲ, ಏಕೆಂದರೆ 4 ನೇ ಚೌಕಟ್ಟು XP ಮತ್ತು 2003 ಸರ್ವರ್ ಎರಡನ್ನೂ ಬೆಂಬಲಿಸುತ್ತದೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ