āĻāĻ¨ā§āĻāĻžāĻ°āĻ¨ā§āĻ āĻ
āĻ¨ā§āĻ āĻāĻā§āĻ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻŋāĻ¤ āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻ¨ā§āĻāĻžāĻ°āĻ¨ā§āĻā§āĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛āĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ - UDP āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻĄā§āĻāĻžāĻā§āĻ°āĻžāĻŽ āĻāĻŦāĻ āĻ¸āĻŽā§āĻĒā§āĻ°āĻāĻžāĻ° āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻāĻ°āĻ¤ā§ āĻ¨āĻ¯āĻŧ, āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻ āĻ¨ā§āĻĄāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ "āĻĒāĻŋāĻ¯āĻŧāĻžāĻ°-āĻā§-āĻĒāĻŋāĻ¯āĻŧāĻžāĻ°" āĻ¸āĻāĻ¯ā§āĻ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°āĻ¤ā§ āĻ
ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻšāĻ¯āĻŧāĨ¤ āĻāĻ° āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¨āĻāĻļāĻžāĻ° āĻāĻžāĻ°āĻŖā§, āĻāĻ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛āĻāĻŋāĻ° āĻ
āĻ¨ā§āĻāĻā§āĻ˛āĻŋ āĻĒā§āĻ°ā§āĻŦā§ āĻ
āĻĒāĻ°āĻŋāĻāĻ˛ā§āĻĒāĻŋāĻ¤ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ°āĻ¯āĻŧā§āĻā§, āĻ¤āĻŦā§, āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻ¤ā§āĻ°ā§āĻāĻŋāĻā§āĻ˛āĻŋ, āĻ¯ā§āĻŽāĻ¨ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋāĻ° āĻ
āĻāĻžāĻŦ, āĻā§āĻĨāĻžāĻ āĻ
āĻĻā§āĻļā§āĻ¯ āĻšāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧāĻ¨āĻŋāĨ¤ āĻāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻāĻŋ UDP āĻāĻ° āĻāĻĒāĻ° āĻā§āĻ¯āĻžāĻ°āĻžāĻ¨ā§āĻāĻŋāĻ¯ā§āĻā§āĻ¤ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻāĻ°ā§āĨ¤
āĻ¸ā§āĻāĻŋāĻĒāĻ¤ā§āĻ°:
DisposeByTimeout āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ°āĻŋāĻ¸āĻŋāĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻĒāĻžāĻ āĻžāĻ¨ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ
āĻĒā§āĻ°āĻŦā§āĻļ
āĻāĻ¨ā§āĻāĻžāĻ°āĻ¨ā§āĻā§āĻ° āĻŽā§āĻ˛ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ°āĻāĻŋ āĻāĻāĻāĻŋ āĻ¸āĻŽāĻāĻžāĻ¤ā§āĻ¯āĻŧ āĻ āĻŋāĻāĻžāĻ¨āĻž āĻ¸ā§āĻĨāĻžāĻ¨ āĻ§āĻ°ā§ āĻ¨āĻŋāĻ¯āĻŧā§āĻā§ āĻ¯ā§āĻāĻžāĻ¨ā§ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻ¨ā§āĻĄā§āĻ° āĻāĻāĻāĻŋ āĻŦāĻŋāĻļā§āĻŦāĻŦā§āĻ¯āĻžāĻĒā§ āĻāĻŦāĻ āĻ
āĻ¨āĻ¨ā§āĻ¯ āĻāĻāĻĒāĻŋ āĻ āĻŋāĻāĻžāĻ¨āĻž āĻāĻŋāĻ˛ āĻāĻŦāĻ āĻ
āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ¨ā§āĻĄā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻ¯ā§āĻāĻžāĻ¯ā§āĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻāĻ¨ āĻāĻ¨ā§āĻāĻžāĻ°āĻ¨ā§āĻā§āĻ°, āĻāĻ¸āĻ˛ā§, āĻāĻāĻāĻŋ āĻāĻŋāĻ¨ā§āĻ¨ āĻ¸ā§āĻĨāĻžāĻĒāĻ¤ā§āĻ¯ āĻ°āĻ¯āĻŧā§āĻā§ - āĻā§āĻ˛ā§āĻŦāĻžāĻ˛ āĻāĻāĻĒāĻŋ āĻ āĻŋāĻāĻžāĻ¨āĻžāĻā§āĻ˛āĻŋāĻ° āĻāĻāĻāĻŋ āĻāĻ˛āĻžāĻāĻž āĻāĻŦāĻ NAT āĻĄāĻŋāĻāĻžāĻāĻ¸āĻā§āĻ˛āĻŋāĻ° āĻĒāĻŋāĻāĻ¨ā§ āĻ˛ā§āĻāĻžāĻ¨ā§ āĻŦā§āĻ¯āĻā§āĻ¤āĻŋāĻāĻ¤ āĻ āĻŋāĻāĻžāĻ¨āĻž āĻ¸āĻš āĻ
āĻ¨ā§āĻ āĻāĻ˛āĻžāĻāĻžāĨ¤
āĻāĻ¨ā§āĻāĻžāĻ°āĻ¨ā§āĻā§āĻ° āĻāĻ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ°āĻāĻŋ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ-āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻ¯ā§āĻāĻžāĻ¯ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¯āĻĨā§āĻˇā§āĻ āĻ¸āĻ āĻŋāĻ, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻāĻ°āĻž āĻŦā§āĻ¯āĻā§āĻ¤āĻŋāĻāĻ¤ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻā§ āĻĨāĻžāĻāĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻāĻŦāĻ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§āĻ° āĻāĻāĻāĻŋ āĻŦāĻŋāĻļā§āĻŦāĻŦā§āĻ¯āĻžāĻĒā§ āĻ āĻŋāĻāĻžāĻ¨āĻž āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻŋ āĻĻā§āĻāĻŋ āĻ¨ā§āĻĄā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻŦā§āĻ¯āĻā§āĻ¤āĻŋāĻāĻ¤ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĨ¤ āĻĒāĻŋāĻ¯āĻŧāĻžāĻ°-āĻā§-āĻĒāĻŋāĻ¯āĻŧāĻžāĻ° āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻ¯ā§āĻŽāĻ¨ āĻāĻ¯āĻŧā§āĻ¸ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ (āĻ¸ā§āĻāĻžāĻāĻĒ), āĻāĻŽā§āĻĒāĻŋāĻāĻāĻžāĻ°ā§ āĻĻā§āĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ (āĻāĻŋāĻŽāĻāĻŋāĻāĻ¯āĻŧāĻžāĻ°) āĻŦāĻž āĻ āĻ¨āĻ˛āĻžāĻāĻ¨ āĻā§āĻŽāĻŋāĻāĻ¯āĻŧā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĻā§āĻāĻŋ āĻ¨ā§āĻĄā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖāĨ¤
āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĒā§āĻ°āĻžāĻāĻā§āĻ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻā§ āĻĄāĻŋāĻāĻžāĻāĻ¸āĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĒāĻŋāĻ¯āĻŧāĻžāĻ°-āĻā§-āĻĒāĻŋāĻ¯āĻŧāĻžāĻ° āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻšāĻ˛ āĻšā§āĻ˛ āĻĒāĻžāĻā§āĻāĻŋāĻāĨ¤ āĻāĻ āĻā§āĻļāĻ˛āĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ¤ āĻāĻāĻĄāĻŋāĻĒāĻŋ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻāĻĒāĻ° āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻšāĻ¯āĻŧāĨ¤
āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¯āĻĻāĻŋ āĻāĻĒāĻ¨āĻžāĻ° āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻžāĻŦā§ āĻĄā§āĻāĻž āĻ¸āĻ°āĻŦāĻ°āĻžāĻšā§āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻšāĻ¯āĻŧ, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻĒāĻ¨āĻŋ āĻāĻŽā§āĻĒāĻŋāĻāĻāĻžāĻ°ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĢāĻžāĻāĻ˛ āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻāĻ°ā§āĻ¨, āĻ¤āĻžāĻšāĻ˛ā§ UDP āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§ āĻ āĻ¨ā§āĻ āĻ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻšāĻŦā§ āĻāĻžāĻ°āĻŖ UDP āĻāĻāĻāĻŋ āĻā§āĻ¯āĻžāĻ°āĻžāĻ¨ā§āĻāĻŋāĻ¯ā§āĻā§āĻ¤ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¨āĻ¯āĻŧ āĻāĻŦāĻ TCP āĻāĻ° āĻŦāĻŋāĻĒāĻ°ā§āĻ¤ā§ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§ āĻ¨āĻžāĨ¤ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛
āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻā§āĻ¯āĻžāĻ°āĻžāĻ¨ā§āĻāĻŋāĻ¯ā§āĻā§āĻ¤ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻāĻ°āĻ¤ā§, āĻāĻāĻāĻŋ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻ˛ā§āĻ¯āĻŧāĻžāĻ° āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ āĻ¯āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻžāĻ°ā§āĻ¯āĻāĻžāĻ°āĻŋāĻ¤āĻž āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§ āĻāĻŦāĻ UDP-āĻ¤ā§ āĻāĻžāĻ āĻāĻ°ā§āĨ¤
āĻāĻŽāĻŋ āĻ āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§ āĻ¨ā§āĻ āĻāĻ°āĻ¤ā§ āĻāĻžāĻ āĻ¯ā§ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĒā§āĻ°āĻžāĻāĻā§āĻ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻā§ āĻ¨ā§āĻĄāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ TCP āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ TCP āĻšā§āĻ˛ āĻĒāĻžāĻā§āĻāĻŋāĻ āĻā§āĻļāĻ˛ āĻ°āĻ¯āĻŧā§āĻā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ āĻ¨ā§āĻ NAT āĻĄāĻŋāĻāĻžāĻāĻ¸ āĻĻā§āĻŦāĻžāĻ°āĻž āĻāĻāĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ā§āĻ° āĻ āĻāĻžāĻŦā§āĻ° āĻāĻžāĻ°āĻŖā§, āĻāĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ¤ āĻ¸āĻāĻ¯ā§āĻ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻāĻĒāĻžāĻ¯āĻŧ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻŦāĻŋāĻŦā§āĻāĻŋāĻ¤ āĻšāĻ¯āĻŧ āĻ¨āĻžāĨ¤ āĻ¯ā§āĻŽāĻ¨ āĻ¨ā§āĻĄ
āĻāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§āĻ° āĻŦāĻžāĻāĻŋ āĻ āĻāĻļā§āĻ° āĻāĻ¨ā§āĻ¯, āĻāĻŽāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻāĻĒāĻ° āĻĢā§āĻāĻžāĻ¸ āĻāĻ°āĻŦāĨ¤ UDP āĻšā§āĻ˛ āĻĒāĻžāĻā§āĻāĻŋāĻ āĻā§āĻļāĻ˛ā§āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻāĻ°āĻž āĻšāĻŦā§āĨ¤
āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻž
- āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻāĻāĻāĻŋ āĻāĻ¤āĻŋāĻŦāĻžāĻāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻšāĻ¯āĻŧ (āĻ¤āĻĨāĻžāĻāĻĨāĻŋāĻ¤ āĻāĻ¤āĻŋāĻŦāĻžāĻāĻ āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ)
- āĻŦāĻĄāĻŧ āĻĄā§āĻāĻžāĻ° āĻĻāĻā§āĻˇ āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ°ā§āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨, āĻ¯ā§āĻŽāĻ¨ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛āĻā§ āĻ āĻŦāĻļā§āĻ¯āĻ āĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻ°āĻŋāĻ˛ā§ āĻāĻ°āĻž āĻāĻĄāĻŧāĻžāĻ¤ā§ āĻšāĻŦā§
- āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻŦāĻžāĻ¤āĻŋāĻ˛ āĻāĻ°āĻž āĻ¸āĻŽā§āĻāĻŦ āĻšāĻāĻ¯āĻŧāĻž āĻāĻāĻŋāĻ¤ (āĻāĻāĻāĻŋ "āĻŦāĻŋāĻļā§āĻĻā§āĻ§" UDP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻā§āĻˇāĻŽāĻ¤āĻž)
- āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻ¸āĻš āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻŽā§āĻĄ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻžāĻ° āĻā§āĻˇāĻŽāĻ¤āĻž
- āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻĄā§āĻāĻž āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻĢāĻžāĻ°ā§āĻ° āĻŽā§āĻ˛āĻŋāĻ āĻāĻāĻ¨āĻŋāĻ āĻāĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻšāĻ¤ā§ āĻšāĻŦā§
āĻāĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻžāĻā§āĻ˛āĻŋ āĻŽā§āĻ˛āĻ¤ āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ āĻĄā§āĻāĻž āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§ āĻŽāĻŋāĻ˛ā§ āĻ¯āĻžāĻ¯āĻŧ
āĻāĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻžāĻā§āĻ˛āĻŋ āĻŦā§āĻāĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻ¸ā§āĻ¨ TCP āĻāĻŦāĻ UDP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻĻā§āĻāĻŋ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻ āĻ¨ā§āĻĄā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ°ā§āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻĻā§āĻāĻŋāĨ¤ āĻāĻāĻ¯āĻŧ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻŦā§āĨ¤
TCP āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻ
-āĻāĻ¨ā§āĻāĻžāĻ°ā§āĻā§āĻāĻŋāĻ āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ°:
āĻāĻĒāĻ¨āĻŋ āĻĄāĻžāĻ¯āĻŧāĻžāĻā§āĻ°āĻžāĻŽ āĻĨā§āĻā§ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻā§āĻā§āĻ¨, āĻĒā§āĻ¯āĻžāĻā§āĻ āĻšāĻžāĻ°āĻžāĻ¨ā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, TCP āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻļāĻ¨āĻžāĻā§āĻ¤ āĻāĻ°āĻŦā§ āĻāĻŦāĻ āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻ
āĻāĻļā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻāĻŋāĻā§āĻāĻžāĻ¸āĻž āĻāĻ°ā§ āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻāĻžāĻā§ āĻ°āĻŋāĻĒā§āĻ°ā§āĻ āĻāĻ°āĻŦā§āĨ¤
UDP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ°:
UDP āĻā§āĻ¨ā§ āĻā§āĻˇāĻ¤āĻŋ āĻ¸āĻ¨āĻžāĻā§āĻ¤āĻāĻ°āĻŖ āĻĒāĻĻāĻā§āĻˇā§āĻĒ āĻ¨ā§āĻ¯āĻŧ āĻ¨āĻžāĨ¤ UDP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻ¤ā§āĻ°ā§āĻāĻŋāĻ° āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖāĻāĻžāĻŦā§ āĻ
ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ā§āĻ° āĻĻāĻžāĻ¯āĻŧāĻŋāĻ¤ā§āĻŦāĨ¤
TCP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻ¸āĻ¨āĻžāĻā§āĻ¤āĻāĻ°āĻŖ āĻāĻāĻāĻŋ āĻļā§āĻˇ āĻ¨ā§āĻĄā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°ā§, āĻ¸ā§āĻ āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻ āĻŦāĻ¸ā§āĻĨāĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°ā§, āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻšā§āĻĄāĻžāĻ°ā§ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻŦāĻžāĻāĻā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°ā§ āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻ¨āĻŽā§āĻŦāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤āĻŋāĻā§āĻ˛āĻŋāĻā§ āĻ āĻŦāĻšāĻŋāĻ¤ āĻāĻ°ā§āĨ¤
āĻ āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤āĻāĻžāĻŦā§, āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻāĻ¨ā§āĻ¨āĻ¤ āĻāĻ°āĻ¤ā§ (āĻ āĻ°ā§āĻĨāĻžā§ āĻāĻāĻāĻŋ āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻ¨āĻž āĻĒā§āĻ¯āĻŧā§ āĻāĻāĻžāĻ§āĻŋāĻ āĻ¸ā§āĻāĻŽā§āĻ¨ā§āĻ āĻĒāĻžāĻ āĻžāĻ¨), TCP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¤āĻĨāĻžāĻāĻĨāĻŋāĻ¤ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻāĻāĻ¨ā§āĻĄā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ - āĻ¸ā§āĻāĻŽā§āĻ¨ā§āĻā§āĻ° āĻĒā§āĻ°ā§āĻ°āĻ āĻ¯ā§ āĻĄā§āĻāĻž āĻĒāĻžāĻāĻ¯āĻŧāĻžāĻ° āĻāĻļāĻž āĻāĻ°ā§āĻ¨ āĻ¤āĻžāĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻŦāĻžāĻāĻāĨ¤
TCP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻ°āĻ āĻ¤āĻĨā§āĻ¯ā§āĻ° āĻāĻ¨ā§āĻ¯, āĻĻā§āĻā§āĻ¨
āĻāĻĒāĻ°ā§āĻā§āĻ¤ āĻĨā§āĻā§, āĻāĻāĻž āĻ¸ā§āĻĒāĻˇā§āĻ āĻ¯ā§ UDP āĻāĻ° āĻāĻĒāĻ° āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ (āĻāĻ° āĻĒāĻ°ā§ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻ˛ā§āĻ˛ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP), āĻāĻāĻŋ āĻāĻŋāĻ¸āĻŋāĻĒāĻŋ-āĻāĻ° āĻŽāĻ¤ā§ āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻ¯āĻĨāĻž:
- āĻ¸āĻāĻ¯ā§āĻ āĻ āĻŦāĻ¸ā§āĻĨāĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°ā§āĻ¨
- āĻ¸ā§āĻāĻŽā§āĻ¨ā§āĻ āĻ¨āĻŽā§āĻŦāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻ¨
- āĻŦāĻŋāĻļā§āĻˇ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻ¨
- āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻĨā§āĻ°ā§āĻĒā§āĻ āĻŦāĻžāĻĄāĻŧāĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ¸āĻ°āĻ˛ā§āĻā§āĻ¤ āĻāĻāĻ¨ā§āĻĄā§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻ¨
āĻāĻĒāĻ°āĻ¨ā§āĻ¤ā§, āĻāĻĒāĻ¨āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨:
- āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻāĻ¸ā§āĻĨāĻžāĻ¨ āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻāĻ°āĻ¤ā§ āĻāĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻļā§āĻ°ā§āĻ° āĻ¸āĻāĻā§āĻ¤
- āĻāĻĒāĻ¸ā§āĻā§āĻ°āĻŋāĻŽ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°ā§āĻ°āĻŖ āĻāĻ°āĻ¤ā§ āĻāĻŦāĻ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¸āĻāĻ¸ā§āĻĨāĻžāĻ¨ āĻĒā§āĻ°āĻāĻžāĻļ āĻāĻ°āĻ¤ā§ āĻāĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻ¸āĻŽāĻžāĻĒā§āĻ¤āĻŋ āĻ¸āĻāĻā§āĻ¤ āĻāĻ°ā§āĻ¨
- āĻ¸āĻāĻ¯ā§āĻ-āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛āĻā§ "āĻŦāĻŋāĻļā§āĻĻā§āĻ§" UDP āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¨āĻŋāĻˇā§āĻā§āĻ°āĻŋāĻ¯āĻŧ āĻāĻ°āĻžāĻ° āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻāĻŋāĻ¨
āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻšā§āĻĄāĻžāĻ°
āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŦā§āĻ¨ āĻ¯ā§ āĻāĻāĻāĻŋ UDP āĻĄā§āĻāĻžāĻā§āĻ°āĻžāĻŽ āĻāĻāĻāĻŋ āĻāĻāĻĒāĻŋ āĻĄā§āĻāĻžāĻā§āĻ°āĻžāĻŽā§ āĻāĻ¨āĻā§āĻ¯āĻžāĻĒāĻ¸ā§āĻ˛ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻāĻāĻŋ UDP āĻĄā§āĻāĻžāĻā§āĻ°āĻžāĻŽā§ āĻ¯āĻĨāĻžāĻ¯āĻĨāĻāĻžāĻŦā§ "āĻŽā§āĻĄāĻŧāĻžāĻ¨ā§" āĻšāĻ¯āĻŧāĨ¤
āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻšā§āĻĄāĻžāĻ° āĻāĻ¨āĻā§āĻ¯āĻžāĻĒāĻ¸ā§āĻ˛ā§āĻļāĻ¨:
āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻšā§āĻĄāĻžāĻ°ā§āĻ° āĻāĻ āĻ¨ āĻŦā§āĻļ āĻ¸āĻšāĻ:
- āĻĒāĻ¤āĻžāĻāĻž - āĻĒā§āĻ¯āĻžāĻā§āĻ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻĒāĻ¤āĻžāĻāĻž
- MessageType - āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ¸āĻžāĻŦāĻ¸ā§āĻā§āĻ°āĻžāĻāĻŦ āĻāĻ°āĻ¤ā§ āĻāĻĒāĻ¸ā§āĻā§āĻ°āĻŋāĻŽ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°āĻāĻžāĻ°
- āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨āĻāĻāĻĄāĻŋ - āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž, āĻĒā§āĻ°āĻžāĻĒāĻā§āĻ° āĻ āĻŋāĻāĻžāĻ¨āĻž āĻāĻŦāĻ āĻĒā§āĻ°ā§āĻ āĻ¸āĻš, āĻ¸āĻāĻ¯ā§āĻāĻāĻŋāĻā§ āĻ āĻ¨āĻ¨ā§āĻ¯āĻāĻžāĻŦā§ āĻ¸āĻ¨āĻžāĻā§āĻ¤ āĻāĻ°ā§
- PacketNumber - āĻĒā§āĻ¯āĻžāĻā§āĻ āĻ¨āĻŽā§āĻŦāĻ°
- āĻŦāĻŋāĻāĻ˛ā§āĻĒ - āĻ āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻŦāĻŋāĻāĻ˛ā§āĻĒāĨ¤ āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻāĻāĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°āĻ¤ā§ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻšāĻ¯āĻŧ
āĻĒāĻ¤āĻžāĻāĻžāĻā§āĻ˛āĻŋ āĻ¨āĻŋāĻŽā§āĻ¨āĻ°ā§āĻĒ:
- FirstPacket - āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻ
- NoAsk - āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻāĻŋāĻ° āĻ¸āĻā§āĻ°āĻŋāĻ¯āĻŧ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻ¨ā§āĻ
- LastPacket - āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻļā§āĻˇ āĻĒā§āĻ¯āĻžāĻā§āĻ
- RequestForPacket - āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻŦāĻž āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻ¨ā§āĻ°ā§āĻ§
āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¨ā§āĻ¤āĻŋ
āĻ¯ā§āĻšā§āĻ¤ā§ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻĻā§āĻāĻŋ āĻ¨ā§āĻĄā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°ā§āĻ°āĻŖā§āĻ° āĻāĻĒāĻ° āĻĻā§āĻˇā§āĻāĻŋ āĻ¨āĻŋāĻŦāĻĻā§āĻ§ āĻāĻ°ā§, āĻ¤āĻžāĻ āĻāĻāĻŋ āĻ āĻŦāĻļā§āĻ¯āĻ āĻ āĻ¨ā§āĻ¯ āĻĻāĻŋāĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻ¤ā§ āĻ¸āĻā§āĻˇāĻŽ āĻšāĻŦā§āĨ¤ āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻ¤ā§, āĻĒā§āĻ°ā§āĻ°āĻ āĻĢāĻžāĻ°ā§āĻ¸ā§āĻāĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻ¤āĻžāĻāĻž āĻ¸āĻš āĻāĻāĻāĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻžāĻ āĻžāĻ¨, āĻ¯āĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻ āĻ°ā§āĻĨ āĻšāĻŦā§ āĻ¸āĻāĻ¯ā§āĻāĻāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻˇā§āĻ āĻŋāĻ¤ āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ, āĻŦāĻž, āĻ āĻ¨ā§āĻ¯ āĻāĻĨāĻžāĻ¯āĻŧ, āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻ, āĻ¸āĻ°ā§āĻŦāĻĻāĻž PacketNumber āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ° āĻŽāĻžāĻ¨ āĻ¸āĻĢāĻ˛āĻāĻžāĻŦā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋāĻ° āĻŦā§āĻšāĻ¤ā§āĻ¤āĻŽ PacketNumber āĻŽāĻžāĻ¨ā§āĻ° āĻā§āĻ¯āĻŧā§ āĻāĻāĻāĻŋāĻ¤ā§ āĻ¸ā§āĻ āĻāĻ°ā§āĨ¤ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻŦāĻŋāĻāĻ˛ā§āĻĒ āĻā§āĻˇā§āĻ¤ā§āĻ°āĻāĻŋ āĻšāĻ˛ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻāĻāĻžāĻ°āĨ¤
āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻ¤ā§ āĻāĻāĻāĻŋ āĻ
āĻ¨ā§āĻ°ā§āĻĒ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ LastPacket āĻĒāĻ¤āĻžāĻāĻž āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻļā§āĻˇ āĻĒā§āĻ¯āĻžāĻā§āĻā§ āĻ¸ā§āĻ āĻāĻ°āĻž āĻāĻā§āĨ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻā§, āĻļā§āĻˇ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž + 1 āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļāĻŋāĻ¤ āĻšāĻ¯āĻŧ, āĻ¯āĻžāĻ° āĻ
āĻ°ā§āĻĨ āĻā§āĻ°āĻšāĻŖāĻāĻžāĻ°ā§ āĻĒāĻā§āĻˇā§āĻ° āĻāĻ¨ā§āĻ¯ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻāĻŋāĻ° āĻ¸āĻĢāĻ˛ āĻŦāĻŋāĻ¤āĻ°āĻŖāĨ¤
āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻŦāĻ āĻ¸āĻŽāĻžāĻĒā§āĻ¤āĻŋ āĻāĻŋāĻ¤ā§āĻ°:
āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻž āĻšāĻ˛ā§, āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧāĨ¤ āĻĄā§āĻāĻž āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻŦā§āĻ˛āĻā§ āĻĒā§āĻ°ā§āĻ°āĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻŦā§āĻ˛āĻā§, āĻļā§āĻˇāĻāĻŋ āĻāĻžāĻĄāĻŧāĻž, āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻ¸āĻāĻā§āĻ¯āĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻāĻŋ āĻ°āĻŋāĻ¸āĻŋāĻ/āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻ āĻāĻāĻ¨ā§āĻĄā§ āĻ¸āĻžāĻāĻā§āĻ° āĻ¸āĻŽāĻžāĻ¨āĨ¤ āĻĄā§āĻāĻžāĻ° āĻļā§āĻˇ āĻŦā§āĻ˛āĻā§ āĻāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĨāĻžāĻāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻŦā§āĻ˛āĻ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻĒāĻ°ā§, āĻĒā§āĻ°ā§āĻ°āĻŖāĻāĻžāĻ°ā§ āĻĒāĻā§āĻˇ āĻāĻāĻāĻŋ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻŦāĻž āĻšāĻžāĻ°āĻžāĻ¨ā§ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ
āĻ¨ā§āĻ°ā§āĻ§ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ
āĻĒā§āĻā§āĻˇāĻž āĻāĻ°ā§, āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒāĻžāĻāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ°āĻŋāĻ¸āĻŋāĻ/āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻ āĻāĻāĻ¨ā§āĻĄā§āĻāĻŋ āĻā§āĻ˛āĻž āĻ°ā§āĻā§āĨ¤ āĻŦā§āĻ˛āĻ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋāĻ° āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻĒāĻžāĻāĻ¯āĻŧāĻžāĻ° āĻĒāĻ°, āĻ°āĻŋāĻ¸āĻŋāĻ/āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻ āĻāĻāĻ¨ā§āĻĄā§ āĻļāĻŋāĻĢāĻ āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻŦā§āĻ˛āĻ āĻĄā§āĻāĻž āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧāĨ¤
āĻā§āĻ°āĻšāĻŖāĻāĻžāĻ°ā§ āĻĒāĻā§āĻˇ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻā§āĻ°āĻšāĻŖ āĻāĻ°ā§āĨ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻāĻāĻ¨ā§āĻĄā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĒāĻĄāĻŧā§ āĻāĻŋāĻ¨āĻž āĻ¤āĻž āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻŦāĻ āĻĄā§āĻĒā§āĻ˛āĻŋāĻā§āĻ āĻ¯āĻž āĻāĻāĻ¨ā§āĻĄā§āĻ¤ā§ āĻĒāĻĄāĻŧā§ āĻ¨āĻž āĻ¤āĻž āĻĢāĻŋāĻ˛ā§āĻāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻāĻžāĻ°āĻŖ āĻ¯āĻĻāĻŋ āĻāĻāĻ¨ā§āĻĄā§āĻ° āĻāĻāĻžāĻ° āĻ¸ā§āĻĨāĻŋāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻĒā§āĻ°āĻžāĻĒāĻ āĻāĻŦāĻ āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻ āĻĨāĻžāĻā§, āĻ¤āĻžāĻšāĻ˛ā§ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻāĻāĻŋ āĻŦā§āĻ˛āĻ āĻā§āĻˇāĻ¤āĻŋ āĻāĻžāĻĄāĻŧāĻžāĻ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°āĻžāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻāĻāĻ¨ā§āĻĄā§āĻāĻŋ āĻĄāĻžāĻāĻž āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻŦā§āĻ˛āĻā§āĻ° āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻā§āĻ°āĻšāĻŖ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ°āĻŋāĻ¤ āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻšāĻ¯āĻŧ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻ¯āĻĻāĻŋ āĻāĻžāĻā§āĻ° āĻāĻžāĻāĻŽāĻžāĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŋāĻ¤ āĻ¸āĻŽāĻ¯āĻŧā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻ¨ā§āĻĄā§āĻāĻŋ āĻĒā§āĻ°āĻŖ āĻ¨āĻž āĻšāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻāĻāĻŋ āĻā§āĻ āĻļā§āĻ°ā§ āĻāĻ°āĻž āĻšāĻŦā§ āĻ¯ā§ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĻ¨āĻŋ āĻāĻŦāĻ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ
āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻŦā§āĨ¤
āĻ°āĻŋāĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻĄāĻžāĻ¯āĻŧāĻžāĻā§āĻ°āĻžāĻŽ:
āĻāĻžāĻāĻŽāĻāĻāĻ āĻāĻŦāĻ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻāĻžāĻāĻŽāĻžāĻ°
āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ āĻ¨āĻž āĻā§āĻ¨ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻžāĻ°āĻŖ āĻāĻā§āĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻ¯āĻĻāĻŋ āĻā§āĻ°āĻšāĻŖāĻāĻžāĻ°ā§ āĻĒāĻā§āĻˇ āĻ āĻĢāĻ˛āĻžāĻāĻ¨ā§ āĻĨāĻžāĻā§āĨ¤ āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻ¸āĻāĻ¯ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ā§āĻ° āĻā§āĻˇā§āĻāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ, āĻ¸āĻāĻ¯ā§āĻāĻāĻŋ āĻāĻžāĻāĻŽāĻāĻāĻ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦāĻ¨ā§āĻ§ āĻšāĻ¯āĻŧā§ āĻ¯āĻžāĻŦā§āĨ¤ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻŽāĻž āĻ¸ā§āĻ āĻāĻ°āĻ¤ā§ āĻĻā§āĻāĻŋ āĻāĻžāĻāĻŽāĻžāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĨ¤ āĻĒā§āĻ°āĻĨāĻŽāĻāĻŋ, āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻŋāĻ āĻāĻžāĻāĻŽāĻžāĻ°, āĻĻā§āĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻšā§āĻ¸ā§āĻ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻ¤ā§ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻšāĻ¯āĻŧāĨ¤ āĻ¯āĻĻāĻŋ āĻāĻāĻŋ āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻĒāĻā§āĻˇ āĻĨā§āĻā§ āĻĢāĻžāĻ¯āĻŧāĻžāĻ° āĻšāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻļā§āĻˇ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻĒā§āĻ¯āĻžāĻā§āĻāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧāĨ¤ āĻ¯āĻĻāĻŋ āĻĒā§āĻ°āĻžāĻĒāĻā§āĻ° āĻāĻžāĻā§ āĻāĻžāĻāĻŽāĻžāĻ°ā§āĻ° āĻŽā§āĻ¯āĻŧāĻžāĻĻ āĻļā§āĻˇ āĻšāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧāĨ¤
āĻ¨ā§āĻĄāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¯ā§āĻāĻžāĻ¯ā§āĻā§āĻ° āĻ āĻāĻžāĻŦā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ¸āĻāĻ¯ā§āĻāĻāĻŋ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĻā§āĻŦāĻŋāĻ¤ā§āĻ¯āĻŧ āĻāĻžāĻāĻŽāĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨āĨ¤ āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻĒāĻā§āĻˇā§āĻ° āĻāĻ¨ā§āĻ¯, āĻāĻāĻŋ āĻāĻžāĻ°ā§āĻ¯āĻāĻ°ā§ āĻāĻžāĻāĻŽāĻžāĻ°ā§āĻ° āĻŽā§āĻ¯āĻŧāĻžāĻĻ āĻļā§āĻˇ āĻšāĻāĻ¯āĻŧāĻžāĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻĨā§āĻ āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻĻā§āĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ¨ā§āĻĄ āĻĨā§āĻā§ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻĒā§āĻā§āĻˇāĻž āĻāĻ°ā§āĨ¤ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻ¸āĻŽāĻ¯āĻŧā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻā§āĻ¨ā§ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¨āĻž āĻĨāĻžāĻāĻ˛ā§, āĻ¸āĻāĻ¯ā§āĻāĻāĻŋ āĻŦāĻ¨ā§āĻ§ āĻāĻ°ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻ¸āĻāĻ¸ā§āĻĨāĻžāĻ¨āĻā§āĻ˛āĻŋ āĻā§āĻĄāĻŧā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧāĨ¤ āĻ°āĻŋāĻ¸āĻŋāĻāĻŋāĻ āĻ¸āĻžāĻāĻĄā§āĻ° āĻāĻ¨ā§āĻ¯, āĻāĻ¯āĻŧāĻžāĻ°ā§āĻ āĻāĻžāĻāĻŽāĻžāĻ° āĻĻā§āĻāĻŦāĻžāĻ° āĻļā§āĻˇ āĻšāĻāĻ¯āĻŧāĻžāĻ° āĻĒāĻ° āĻāĻžāĻ¨ā§āĻāĻļāĻ¨ āĻā§āĻ˛ā§āĻ āĻāĻžāĻāĻŽāĻžāĻ° āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧāĨ¤ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻā§āĻˇāĻ¤āĻŋāĻ° āĻŦāĻŋāĻ°ā§āĻĻā§āĻ§ā§ āĻŦā§āĻŽāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĨ¤ āĻāĻžāĻāĻŽāĻžāĻ°ā§āĻ° āĻŽā§āĻ¯āĻŧāĻžāĻĻ āĻļā§āĻˇ āĻšāĻ¯āĻŧā§ āĻā§āĻ˛ā§, āĻ¸āĻāĻ¯ā§āĻāĻāĻŋāĻ āĻŦāĻ¨ā§āĻ§ āĻšāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧ āĻāĻŦāĻ āĻ¸āĻāĻ¸ā§āĻĨāĻžāĻ¨ āĻĒā§āĻ°āĻāĻžāĻļ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤
āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻ¸ā§āĻā§āĻ āĻĄāĻžāĻ¯āĻŧāĻžāĻā§āĻ°āĻžāĻŽ
āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻ¨ā§āĻ¤āĻŋāĻā§āĻ˛āĻŋ āĻāĻāĻāĻŋ āĻ¸āĻ¸ā§āĻŽ āĻ°āĻžāĻˇā§āĻā§āĻ° āĻŽā§āĻļāĻŋāĻ¨ā§ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻ¯āĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻ
āĻŦāĻ¸ā§āĻĨāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻ¯ā§āĻā§āĻ¤āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻĻāĻžāĻ¯āĻŧā§āĨ¤
āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP āĻ¸ā§āĻā§āĻ āĻĄāĻžāĻ¯āĻŧāĻžāĻā§āĻ°āĻžāĻŽ:
āĻŦāĻ¨ā§āĻ§ - āĻāĻāĻŋ āĻāĻ¸āĻ˛ā§ āĻāĻāĻāĻŋ āĻ°āĻžāĻˇā§āĻā§āĻ° āĻ¨āĻ¯āĻŧ, āĻāĻāĻŋ āĻ
āĻā§āĻŽā§āĻāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻļā§āĻ°ā§ āĻāĻŦāĻ āĻļā§āĻˇ āĻŦāĻŋāĻ¨ā§āĻĻā§āĨ¤ āĻ°āĻžāĻˇā§āĻā§āĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻŦāĻ¨ā§āĻ§ āĻāĻāĻāĻŋ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻāĻ¨ā§āĻā§āĻ°ā§āĻ˛ āĻŦā§āĻ˛āĻ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻšāĻ¯āĻŧ, āĻ¯āĻž āĻāĻāĻāĻŋ āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ UDP āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°ā§, āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋāĻā§ āĻ¯āĻĨāĻžāĻ¯āĻĨ āĻ¸āĻāĻ¯ā§āĻā§ āĻĢāĻ°ā§āĻ¯āĻŧāĻžāĻ°ā§āĻĄ āĻāĻ°ā§ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ āĻļā§āĻ°ā§ āĻāĻ°ā§āĨ¤
FirstPacketSending - āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻž āĻ¯ā§āĻāĻžāĻ¨ā§ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ˛ā§ āĻŦāĻšāĻŋāĻ°ā§āĻāĻžāĻŽā§ āĻ¸āĻāĻ¯ā§āĻ āĻšāĻ¯āĻŧāĨ¤
āĻāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ, āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧāĨ¤ āĻĒāĻžāĻ āĻžāĻ¨ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻāĻžāĻĄāĻŧāĻž āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻāĻŋāĻ āĻāĻāĻŽāĻžāĻ¤ā§āĻ° āĻ°āĻžāĻˇā§āĻā§āĻ° āĻ¯ā§āĻāĻžāĻ¨ā§ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧāĨ¤
āĻ¸ā§āĻ¨ā§āĻĄāĻŋāĻ āĻ¸āĻžāĻāĻā§āĻ˛ - āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒā§āĻ°ā§āĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻĨāĻ˛ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĨ¤
āĻ°āĻžāĻā§āĻ¯ āĻĨā§āĻā§ āĻāĻāĻŋāĻ¤ā§ āĻāĻ¤ā§āĻ¤āĻ°āĻŖ FirstPacketSending āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻĒāĻ°ā§ āĻŦāĻžāĻšāĻŋāĻ¤ āĻšāĻ¯āĻŧ. āĻāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧāĻ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻāĻŦāĻ āĻĒā§āĻ¨āĻāĻĒā§āĻ°āĻāĻžāĻ°ā§āĻ° āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻāĻ¸ā§āĨ¤ āĻāĻāĻŋ āĻĨā§āĻā§ āĻĒā§āĻ°āĻ¸ā§āĻĨāĻžāĻ¨ āĻĻā§āĻāĻŋ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ¸āĻŽā§āĻāĻŦ - āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻāĻŋāĻ° āĻ¸āĻĢāĻ˛ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻŦāĻž āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻŽāĻžāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§āĨ¤
āĻĢāĻžāĻ°ā§āĻ¸ā§āĻāĻĒā§āĻ¯āĻžāĻā§āĻ āĻ°āĻŋāĻ¸āĻŋāĻāĻĄ - āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°āĻžāĻĒāĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĨ¤
āĻāĻāĻŋ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ā§āĻ° āĻļā§āĻ°ā§āĻ° āĻ¸āĻ āĻŋāĻāĻ¤āĻž āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°ā§, āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻžāĻ āĻžāĻŽā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§ āĻāĻŦāĻ āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻĒā§āĻ°āĻžāĻĒā§āĻ¤āĻŋāĻ° āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻĒāĻžāĻ āĻžāĻ¯āĻŧāĨ¤
āĻāĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¯āĻž āĻāĻāĻāĻŋ āĻāĻāĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻ¨āĻŋāĻ¯āĻŧā§ āĻāĻ āĻŋāĻ¤ āĻāĻŦāĻ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻĒā§āĻ°āĻŽāĻžāĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ¨āĻž āĻāĻ°ā§āĻ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛, āĻāĻāĻŋāĻ āĻāĻāĻŽāĻžāĻ¤ā§āĻ° āĻ°āĻžāĻˇā§āĻā§āĻ°āĨ¤ āĻāĻ āĻāĻžāĻ¤ā§āĻ¯āĻŧ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§, āĻ¸āĻāĻ¯ā§āĻāĻāĻŋ āĻŦāĻ¨ā§āĻ§ āĻšāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧāĨ¤
āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤āĻāĻ°āĻ¨ā§āĻ° - āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻā§āĻ°āĻšāĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻŽā§āĻ˛āĻŋāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĨ¤
āĻāĻāĻŋ āĻ āĻ¸ā§āĻĨāĻžāĻ¯āĻŧā§ āĻ¸āĻā§āĻāĻ¯āĻŧāĻ¸ā§āĻĨāĻžāĻ¨ā§ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻ˛āĻŋāĻā§, āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻā§āĻˇāĻ¤āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻā§āĻ āĻāĻ°ā§, āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋāĻ° āĻāĻāĻāĻŋ āĻŦā§āĻ˛āĻ āĻāĻŦāĻ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻĒāĻžāĻ āĻžāĻ¯āĻŧ āĻāĻŦāĻ āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻžāĻ āĻžāĻ¯āĻŧāĨ¤ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ¸āĻĢāĻ˛āĻāĻžāĻŦā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤āĻŋāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻ¸āĻāĻ¯ā§āĻāĻāĻŋ āĻ°āĻžāĻā§āĻ¯ā§ āĻāĻ˛ā§ āĻ¯āĻžāĻ¯āĻŧ āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻšā§ā§āĻā§, āĻ āĻ¨ā§āĻ¯āĻĨāĻžāĻ¯āĻŧ, āĻāĻāĻāĻŋ āĻāĻžāĻāĻŽāĻāĻāĻ āĻĒā§āĻ°āĻ¸ā§āĻĨāĻžāĻ¨ āĻāĻ°ā§āĨ¤
āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻšā§ā§āĻā§ - āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ¸āĻĢāĻ˛āĻāĻžāĻŦā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤āĻŋāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ¸āĻāĻ¯ā§āĻ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻžāĨ¤
āĻāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻ¸āĻŽāĻžāĻŦā§āĻļā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻŦāĻ āĻ¸ā§āĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ¯āĻāĻ¨ āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻĒāĻĨā§ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻāĻŋāĻ° āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖ āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻā§āĻā§āĨ¤ āĻāĻ āĻ āĻŦāĻ¸ā§āĻĨāĻž āĻāĻāĻāĻŋ āĻāĻžāĻāĻŽāĻāĻāĻ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§āĻ°āĻ¸ā§āĻĨāĻžāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¸āĻāĻ¯ā§āĻ āĻ¸āĻĢāĻ˛āĻāĻžāĻŦā§ āĻŦāĻ¨ā§āĻ§ āĻŦāĻ˛ā§ āĻŽāĻ¨ā§ āĻāĻ°āĻž āĻšāĻ¯āĻŧ.
āĻā§āĻĄā§āĻ° āĻāĻ°āĻ āĻāĻā§āĻ°ā§āĨ¤ āĻ¸āĻāĻā§āĻ°āĻŽāĻŖ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻāĻāĻ¨āĻŋāĻ
āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ UDP-āĻāĻ° āĻŽā§āĻ˛ āĻāĻĒāĻžāĻĻāĻžāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻšāĻ˛ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻāĻ¨ā§āĻā§āĻ°ā§āĻ˛ āĻŦā§āĻ˛āĻāĨ¤ āĻāĻ āĻŦā§āĻ˛āĻā§āĻ° āĻāĻžāĻ āĻšāĻ˛ āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ āĻ¸āĻāĻ¯ā§āĻ āĻāĻŦāĻ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ āĻāĻĒāĻžāĻĻāĻžāĻ¨āĻā§āĻ˛āĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž, āĻ¸āĻāĻļā§āĻ˛āĻŋāĻˇā§āĻ āĻ¸āĻāĻ¯ā§āĻāĻā§āĻ˛āĻŋāĻ¤ā§ āĻāĻāĻ¤ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°āĻž, āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻā§ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°āĻž āĻāĻŦāĻ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ API āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻžāĨ¤ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻāĻ¨ā§āĻā§āĻ°ā§āĻ˛ āĻŦā§āĻ˛āĻ UDP āĻ¸ā§āĻ¤āĻ° āĻĨā§āĻā§ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻā§āĻ°āĻšāĻŖ āĻāĻ°ā§ āĻāĻŦāĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻā§āĻ āĻŽā§āĻļāĻŋāĻ¨ā§ āĻĒāĻžāĻ āĻžāĻ¯āĻŧāĨ¤ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻĒā§āĻ¤ā§, āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ 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;
//...
}
āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻāĻāĻĄāĻŋāĻĒāĻŋ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨:
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;
//...
}
āĻā§āĻĄā§āĻ° āĻāĻ°āĻ āĻāĻā§āĻ°ā§āĨ¤ āĻ°āĻžāĻā§āĻ¯āĻā§āĻ˛āĻŋ
āĻ°āĻžāĻˇā§āĻā§āĻ°āĻā§āĻ˛āĻŋ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ āĻāĻāĻĄāĻŋāĻĒāĻŋ āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻ°āĻžāĻˇā§āĻā§āĻ°ā§āĻ¯āĻŧ āĻŽā§āĻļāĻŋāĻ¨ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°ā§, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋāĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻšāĻ¯āĻŧāĨ¤ āĻŦāĻŋāĻŽā§āĻ°ā§āĻ¤ āĻŦāĻ°ā§āĻ 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();
}
āĻāĻāĻž āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ°āĻžāĻā§āĻ¯ā§ āĻāĻāĻžāĻ°āĻ°āĻžāĻāĻĄ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻšā§ā§āĻā§.
āĻ¸āĻŽāĻžāĻĒā§āĻ¤āĨ¤DisposeByTimeout:
protected override void DisposeByTimeout(object record)
{
ReliableUdpConnectionRecord connectionRecord = (ReliableUdpConnectionRecord) record;
// ŅООйŅĐ°ĐĩĐŧ Ой ŅŅĐŋĐĩŅĐŊĐžĐŧ ĐŋĐžĐģŅŅĐĩĐŊии ŅООйŅĐĩĐŊиŅ
SetAsCompleted(connectionRecord);
}
āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ
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);
}
āĻ¸āĻā§āĻˇāĻŽ āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻšā§ā§āĻā§ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻāĻ˛āĻŽāĻžāĻ¨ āĻāĻžāĻāĻŽāĻžāĻ° āĻŦāĻ¨ā§āĻ§ āĻāĻ°ā§ āĻāĻŦāĻ āĻā§āĻ°āĻžāĻšāĻāĻĻā§āĻ° āĻāĻžāĻā§ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¯āĻŧāĨ¤
āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ:
public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
if (connectionRecord.WaitForPacketsTimer != null)
connectionRecord.WaitForPacketsTimer.Dispose();
// ŅОйиŅĐ°ĐĩĐŧ ŅООйŅĐĩĐŊиĐĩ и ĐŋĐĩŅĐĩĐ´Đ°ĐĩĐŧ ĐĩĐŗĐž ĐŋОдĐŋиŅŅиĐēĐ°Đŧ
ReliableUdpStateTools.CreateMessageFromMemoryStream(connectionRecord);
}
āĻ°āĻŋāĻ¸āĻŋāĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ
āĻ¸āĻā§āĻˇāĻŽ āĻĢāĻžāĻ°ā§āĻ¸ā§āĻāĻĒā§āĻ¯āĻžāĻā§āĻ āĻ°āĻŋāĻ¸āĻŋāĻāĻĄ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻāĻžāĻ āĻšāĻ˛ āĻĒā§āĻ°āĻĨāĻŽ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ¯āĻžāĻā§āĻāĻāĻŋ āĻāĻ¸āĻ˛ā§ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ā§ āĻāĻ¸ā§āĻā§ āĻāĻŋāĻ¨āĻž āĻ¤āĻž āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŖ āĻāĻ°āĻž āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻāĻāĻ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻ¸āĻŽāĻ¨ā§āĻŦāĻ¯āĻŧā§ āĻāĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°āĻžāĨ¤
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);
}
}
āĻ¸āĻā§āĻˇāĻŽ āĻ¸ā§āĻ¨ā§āĻĄāĻŋāĻ āĻ¸āĻžāĻāĻā§āĻ˛ āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋāĻ° āĻ¸ā§āĻŦā§āĻā§āĻ¤āĻŋ āĻāĻŦāĻ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻĒā§āĻ°ā§āĻ°āĻŖā§āĻ° āĻ
āĻ¨ā§āĻ°ā§āĻ§āĻā§āĻ˛āĻŋ āĻā§āĻ°āĻšāĻŖ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻžāĻ°āĻ°āĻžāĻāĻĄ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤
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 āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻĄā§āĻāĻžāĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻžāĻ āĻžāĻ¯āĻŧ, āĻ
āĻĨāĻŦāĻž, āĻ¯āĻĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻāĻŋāĻ° āĻĄā§āĻ˛āĻŋāĻāĻžāĻ°āĻŋ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖā§āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻ¨āĻž āĻšāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻĒā§āĻ°ā§ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĨ¤
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 āĻāĻ˛ āĻāĻ°ā§āĨ¤ āĻāĻ°āĻĒāĻ°ā§, āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻāĻ¨ā§āĻā§āĻ°ā§āĻ˛ āĻŦā§āĻ˛āĻā§āĻ° āĻ¸ā§āĻāĻžāĻ°ā§āĻ āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻāĻžāĻ˛ā§ āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻ¯āĻž āĻ¨āĻ¤ā§āĻ¨ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĄā§āĻāĻž āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻļā§āĻ°ā§ āĻāĻ°ā§āĨ¤
āĻāĻāĻāĻŋ āĻŦāĻšāĻŋāĻ°ā§āĻāĻžāĻŽā§ āĻ¸āĻāĻ¯ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻā§āĻā§:
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 āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§, āĻĒā§āĻ°ā§āĻ°āĻŋāĻ¤ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻā§āĻ°āĻšāĻŖ āĻāĻ°ā§, āĻāĻāĻāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§ āĻ¸āĻāĻ¯ā§āĻ āĻ°ā§āĻāĻ°ā§āĻĄ āĻāĻŦāĻ āĻāĻ āĻĒā§āĻ¯āĻžāĻā§āĻāĻāĻŋāĻā§, āĻāĻāĻāĻŋ āĻĒā§āĻ°ā§āĻŦ-āĻĒāĻžāĻ°ā§āĻ¸āĻĄ āĻšā§āĻĄāĻžāĻ° āĻ¸āĻš, āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ°āĻžāĻā§āĻ¯ā§āĻ° āĻ°āĻŋāĻ¸āĻŋāĻāĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ¤ā§ āĻĒā§āĻ°ā§āĻ°āĻŖ āĻāĻ°ā§ āĻĢāĻžāĻ°ā§āĻ¸ā§āĻāĻĒā§āĻ¯āĻžāĻā§āĻ āĻ°āĻŋāĻ¸āĻŋāĻāĻĄ
āĻĒā§āĻ°āĻžāĻĒā§āĻ¤āĻŋāĻ° āĻĻāĻŋāĻā§ āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻā§āĻā§:
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 State):
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-āĻāĻ° āĻāĻāĻāĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻ
āĻāĻļāĨ¤ āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻŦāĻŋāĻŦā§āĻāĻ¨āĻž āĻāĻ°ā§āĻ¨ āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻāĻāĻŋ āĻŽāĻ§ā§āĻ¯āĻŦāĻ°ā§āĻ¤ā§ āĻ¨ā§āĻĄ āĻŦā§āĻ¯āĻ°ā§āĻĨ āĻšāĻ¯āĻŧā§āĻā§ āĻāĻŦāĻ āĻāĻāĻ¯āĻŧ āĻĻāĻŋāĻ āĻĨā§āĻā§ āĻĄā§āĻāĻž āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻāĻ°āĻž āĻ
āĻ¸āĻŽā§āĻāĻŦ āĻšāĻ¯āĻŧā§ āĻāĻ ā§āĻā§āĨ¤
āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻŽāĻžāĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŋāĻ¤ā§āĻ°:
āĻĄāĻžāĻ¯āĻŧāĻžāĻā§āĻ°āĻžāĻŽ āĻĨā§āĻā§ āĻĻā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧ, āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻāĻžāĻ āĻāĻžāĻāĻŽāĻžāĻ° āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻāĻāĻŋ āĻŦā§āĻ˛āĻ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻĨā§āĻ āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧāĨ¤ āĻāĻāĻŋ āĻ°āĻžāĻā§āĻ¯ā§āĻ° āĻ¸ā§āĻ¨ā§āĻĄāĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ¤ā§ āĻāĻā§ āĻ¸ā§āĻ¨ā§āĻĄāĻŋāĻ āĻ¸āĻžāĻāĻā§āĻ˛.
āĻāĻžāĻā§āĻ° āĻāĻžāĻāĻŽāĻžāĻ° āĻ¸āĻā§āĻˇāĻŽ āĻāĻ°āĻž āĻšāĻā§āĻā§ (SendingCycle āĻ
āĻŦāĻ¸ā§āĻĨāĻž):
public override void SendPacket(ReliableUdpConnectionRecord connectionRecord)
{
// ĐžŅĐŋŅавĐģŅĐĩĐŧ ĐąĐģĐžĐē ĐŋĐ°ĐēĐĩŅОв
// ...
// ĐŋĐĩŅĐĩСаĐŋŅŅĐēĐ°ĐĩĐŧ ŅĐ°ĐšĐŧĐĩŅ ĐŋĐžŅĐģĐĩ ĐžŅĐŋŅавĐēи
connectionRecord.WaitForPacketsTimer.Change( connectionRecord.ShortTimerPeriod, -1 );
if ( connectionRecord.CloseWaitTimer != null )
connectionRecord.CloseWaitTimer.Change( -1, -1 );
}
āĻ¸āĻāĻ¯ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻšāĻ˛ā§ āĻāĻžāĻāĻŽāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧāĻāĻžāĻ˛ āĻ¸ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻĄāĻŋāĻĢāĻ˛ā§āĻ āĻļāĻ°ā§āĻāĻāĻžāĻāĻŽāĻžāĻ° āĻĒāĻŋāĻ°āĻŋāĻ¯āĻŧāĻĄ 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);
// ...
}
āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻŋāĻ āĻāĻžāĻāĻŽāĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ
āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ¨āĻāĻžāĻŽāĻŋāĻ āĻ¸āĻāĻ¯ā§āĻā§ āĻāĻ° āĻā§āĻ¨ā§ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻ¸ā§āĻ¨āĻŋāĨ¤ āĻāĻžāĻāĻŽāĻžāĻ°āĻāĻŋ āĻŦāĻ¨ā§āĻ§ āĻšāĻ¯āĻŧā§ āĻā§āĻ˛ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ¤ā§ āĻāĻ˛ āĻāĻ°āĻ˛, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻā§āĻā§ āĻāĻŦāĻ āĻĒā§āĻ°āĻĨāĻŽāĻŦāĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻ
āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛āĨ¤
āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻ
āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻā§āĻā§ (āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻ
āĻŦāĻ¸ā§āĻĨāĻž):
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 āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ āĻ¸ā§āĻ āĻāĻ°āĻž āĻāĻā§ āĻ¸āĻ¤ā§āĻ¯. āĻāĻ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛āĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻŋāĻ āĻāĻžāĻāĻŽāĻžāĻ° āĻ°āĻŋāĻ¸ā§āĻāĻžāĻ°ā§āĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĻāĻžāĻ¯āĻŧā§āĨ¤
āĻĒā§āĻ°ā§āĻ°āĻā§āĻ° āĻĒāĻā§āĻˇ āĻĨā§āĻā§, āĻāĻ°ā§āĻŽāĻ°āĻ¤ āĻāĻžāĻāĻŽāĻžāĻ°āĻāĻŋāĻ āĻā§āĻ°āĻŋāĻāĻžāĻ° āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻ¸āĻ°ā§āĻŦāĻļā§āĻˇ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻĒā§āĻ¯āĻžāĻā§āĻāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻ¯āĻŧāĨ¤
āĻ¸āĻāĻ¯ā§āĻ āĻŦāĻ¨ā§āĻ§ āĻāĻžāĻāĻŽāĻžāĻ° āĻ¸āĻā§āĻˇāĻŽ āĻāĻ°āĻž āĻšāĻā§āĻā§ (SendingCycle āĻ
āĻŦāĻ¸ā§āĻĨāĻž):
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);
}
}
āĻā§āĻĄā§āĻ° āĻāĻ°āĻ āĻāĻā§āĻ°ā§āĨ¤ āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻĒā§āĻ¨āĻ°ā§āĻĻā§āĻ§āĻžāĻ° āĻāĻ°āĻž āĻšāĻā§āĻā§
āĻĒā§āĻ¯āĻžāĻā§āĻ āĻšāĻžāĻ°āĻžāĻ¨ā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻĄā§āĻāĻž āĻā§āĻ°āĻžāĻ¨ā§āĻ¸āĻŽāĻŋāĻļāĻ¨ āĻ°āĻŋāĻāĻāĻžāĻ°āĻŋ āĻĄāĻžāĻ¯āĻŧāĻžāĻā§āĻ°āĻžāĻŽ:
āĻāĻžāĻāĻŽāĻāĻāĻā§ āĻ¸āĻāĻ¯ā§āĻ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻžāĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻāĻ˛ā§āĻāĻ¨āĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§, āĻ¯āĻāĻ¨ āĻāĻžāĻā§āĻ° āĻāĻžāĻāĻŽāĻžāĻ°ā§āĻ° āĻŽā§āĻ¯āĻŧāĻžāĻĻ āĻļā§āĻˇ āĻšāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧ, āĻ¤āĻāĻ¨ āĻ°āĻŋāĻ¸āĻŋāĻāĻžāĻ° āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻŦā§āĨ¤ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻšāĻžāĻ°āĻžāĻ¨ā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻĒā§āĻ°āĻžāĻĒāĻā§āĻ° āĻāĻžāĻā§ āĻĒā§āĻāĻāĻžāĻ¯āĻŧāĻ¨āĻŋ āĻāĻŽāĻ¨ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻžāĻ° āĻāĻāĻāĻŋ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻ¸āĻāĻāĻ˛āĻ¨ āĻāĻ°āĻž āĻšāĻŦā§āĨ¤ āĻāĻ āĻ¨āĻŽā§āĻŦāĻ°āĻā§āĻ˛āĻŋ āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻ¸āĻāĻ¯ā§āĻā§āĻ° 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);
}
}
// ...
}
}
āĻĒā§āĻ°ā§āĻ°āĻ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻŦāĻŋāĻ¤āĻ°āĻŖā§āĻ° āĻ
āĻ¨ā§āĻ°ā§āĻ§ āĻā§āĻ°āĻšāĻŖ āĻāĻ°āĻŦā§ āĻāĻŦāĻ āĻ
āĻ¨ā§āĻĒāĻ¸ā§āĻĨāĻŋāĻ¤ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋ āĻĒāĻžāĻ āĻžāĻŦā§āĨ¤ āĻāĻāĻŋ āĻ˛āĻā§āĻˇāĻŖā§āĻ¯āĻŧ āĻ¯ā§ āĻāĻ āĻŽā§āĻšā§āĻ°ā§āĻ¤ā§ āĻĒā§āĻ°ā§āĻ°āĻ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻ¸āĻāĻ¯ā§āĻ āĻŦāĻ¨ā§āĻ§ āĻāĻžāĻāĻŽāĻžāĻ° āĻļā§āĻ°ā§ āĻāĻ°ā§āĻā§ āĻāĻŦāĻ āĻ¯āĻāĻ¨ āĻāĻāĻāĻŋ āĻ
āĻ¨ā§āĻ°ā§āĻ§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻšāĻ¯āĻŧ, āĻāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻ¸ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤
āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻĒāĻžāĻ āĻžāĻ¨ā§ āĻšāĻā§āĻā§ (SendingCycle āĻ
āĻŦāĻ¸ā§āĻĨāĻž):
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-āĻ āĻĒā§āĻ°āĻāĻ˛ā§āĻĒā§āĻ° āĻ˛āĻŋāĻā§āĻ:
āĻĻāĻ°āĻāĻžāĻ°ā§ āĻ˛āĻŋāĻā§āĻ āĻāĻŦāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§
- TCP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¸ā§āĻĒā§āĻ¸āĻŋāĻĢāĻŋāĻā§āĻļāĻ¨:
Đ°ĐŊĐŗĐģиКŅĐēĐžĐŧ Đ°ĐŊĐŗĐģиКŅĐēĐžĐŧ иāĻ°āĻžāĻļāĻŋāĻ¯āĻŧāĻžāĻ¨ āĻŽāĻ§ā§āĻ¯ā§ - UDP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ āĻ¸ā§āĻĒā§āĻ¸āĻŋāĻĢāĻŋāĻā§āĻļāĻ¨:
Đ°ĐŊĐŗĐģиКŅĐēĐžĐŧ Đ°ĐŊĐŗĐģиКŅĐēĐžĐŧ иāĻ°āĻžāĻļāĻŋāĻ¯āĻŧāĻžāĻ¨ āĻŽāĻ§ā§āĻ¯ā§ - RUDP āĻĒā§āĻ°ā§āĻā§āĻāĻ˛ā§āĻ° āĻāĻ˛ā§āĻāĻ¨āĻž:
āĻāĻ¸āĻĄāĻŧāĻž-ietf-sigtran-āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯-udp-00 - āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¯ā§āĻā§āĻ¯ āĻĄā§āĻāĻž āĻĒā§āĻ°ā§āĻā§āĻāĻ˛:
āĻāĻ°āĻāĻĢāĻ¸āĻŋ 908 иāĻāĻ°āĻāĻĢāĻ¸āĻŋ 1151 - UDP-āĻāĻ° āĻāĻĒāĻ° āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻ°āĻŖā§āĻ° āĻāĻāĻāĻŋ āĻ¸āĻšāĻ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨:
.NET āĻāĻŦāĻ UDP āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻĒāĻ¨āĻžāĻ° āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻŋāĻ āĻāĻ° āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻ¨āĻŋāĻ¨ - NAT āĻā§āĻ°āĻžāĻāĻžāĻ°ā§āĻ¸āĻžāĻ˛ āĻŽā§āĻāĻžāĻ¨āĻŋāĻāĻŽ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻāĻ°ā§ āĻĒā§āĻ°āĻŦāĻ¨ā§āĻ§:
āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻ āĻ āĻŋāĻāĻžāĻ¨āĻž āĻ āĻ¨ā§āĻŦāĻžāĻĻāĻ āĻā§āĻĄāĻŧā§ āĻĒāĻŋāĻ¯āĻŧāĻžāĻ°-āĻā§-āĻĒāĻŋāĻ¯āĻŧāĻžāĻ° āĻāĻŽāĻŋāĻāĻ¨āĻŋāĻā§āĻļāĻ¨ - āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ āĻŽāĻĄā§āĻ˛ā§āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨:
CLR āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ āĻŽāĻĄā§āĻ˛ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻž иāĻāĻŋāĻāĻžāĻŦā§ IAsyncResult āĻĄāĻŋāĻāĻžāĻāĻ¨ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻŦā§āĻ¨ - āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ āĻŽāĻĄā§āĻ˛āĻā§ āĻāĻžāĻ¸ā§āĻ-āĻāĻŋāĻ¤ā§āĻ¤āĻŋāĻ āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨ā§ āĻĒā§āĻ°ā§āĻ āĻāĻ°āĻž (TAP-āĻ APM):
TPL āĻāĻŦāĻ āĻāĻ¤āĻŋāĻšā§āĻ¯āĻāĻ¤ .NET āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ
āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻĒā§āĻ°āĻāĻžāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻ¨ā§āĻāĻžāĻ°āĻĒ āĻāĻ°ā§āĻ¨
āĻāĻĒāĻĄā§āĻ: āĻāĻĒāĻ¨āĻžāĻā§ āĻ§āĻ¨ā§āĻ¯āĻŦāĻžāĻĻ
āĻāĻ¤ā§āĻ¸: www.habr.com