Sobes.tech
Middle+

Ինչպե՞ս ապահովել UDP պրոտոկոլի միջոցով տվյալների երաշխավորված առաքումը։

sobes.tech AI

Պատասխան AI-ից

UDP միջոցով երաշխավորված առաքումը, որպես կապի հաստատում և երաշխիք չպարունակող պրոտոկոլ, պահանջում է ապահովել հուսալիության մեխանիզմներ հավելվածի մակարդակով կամ middleware- ի օգտագործմամբ: Հիմնական մոտեցումները ներառում են՝

  1. Հաստատման մեխանիզմներ (Acknowledgements - ACK): Ուղարկողը յուրաքանչյուր datagram-ում ներառում է նույնականացուցիչ (օրինակ՝ հերթական համարը): Ստացողը ուղարկում է հաստատում յուրաքանչյուր հաջողությամբ ստացված datagram-ի համար:
  2. Վերականգնումների մեխանիզմներ (Retransmission): Ուղարկողը սահմանում է ժամացույց՝ datagram-ի ուղարկումից հետո: Եթե հաստատում չստացվի ժամացույցի ավարտից առաջ, datagram-ը համարվում է կորած և ուղարկվում է կրկին:
  3. Դուրկլատների վերահսկման մեխանիզմներ: Ստացողը հետևում է ստացված datagram-ների նույնականացուցիչներին և մերժում կրկնօրինակները, եթե դրանք հայտնվում են վերականգնումների արդյունքում:
  4. Տարածման վերահսկման մեխանիզմներ: Թեև UDP-ն երաշխավորում է կարգը, հավելվածը կարող է օգտագործել հերթական համարը datagram-ների վերականգման համար:
  5. Հոսքի վերահսկում: Պահանջի դեպքում կարող է իրականացնել մեխանիզմ, որը կանխում է ստացող բուֆերի լցվածությունը:

Այս մեխանիզմների իրականացմանը պահանջվում է զգալի ջանքեր հավելվածի մակարդակով կամ հատուկ գրադարանների/protocol-ների օգտագործմամբ, օրինակ՝

  • Reliable User Datagram Protocol (RUDP): UDP-ի ընդլայնում, որը ավելացնում է հուսալիություն:
  • Quic: Google-ի կողմից մշակված տրանսպորտային պրոտոկոլ, որը աշխատում է UDP-ի վրա և ապահովում է TCP-ի նման ֆունկցիոնալություն (հուսալիություն, հոսքի կառավարում, անվտանգություն), բայց բարելավված ժամանակով կապ հաստատելու և փաթեթների կորուստների նվազեցմամբ:
  • Անցումային ժամանակի պրոտոկոլներ՝ մասնակի հուսալիությամբ: Օրինակ՝ Secure Real-time Transport Protocol (SRTP) կարող է ներառել ընտրովի հուսալիության մեխանիզմներ:

Նմուշային տրամաբանությունը ուղարկողի կողմից՝

# սիմվոլիկ կոդ՝ բացատրության համար

data_to_send = [...] # տվյալների ցանկ
sent_packets = {}    # բառարան՝ հերթական համարը -> (տվյալներ, ուղարկման ժամանակ)
next_seq_num = 0
ack_timeout = 0.1    # վայրկյան
max_retransmissions = 5

յուր data-ի համար:
    paket = (next_seq_num, data)
    send_udp(paket)
    sent_packets[next_seq_num] = (paket, time.time(), 0) # փաթեթ, ուղարկման ժամանակ, կրկնությունների քանակ
    next_seq_num += 1

մինչև, որ(sent_packets):
    # սպասում ենք հաստատումներին
    acks = receive_acks() # հաստատումների ստացման սիմուլյացիա
    յուրաքանչյուր seq_num-ով acks-ում:
        եթե seq_num(sent_packets):
            del sent_packets[seq_num] # հեռացնում ենք սպասող ցուցակից

    # ժամկետների ստուգում և կրկնակի ուղարկում
    current_time = time.time()
    packets_to_retransmit = []
    յուրաքանչյուր seq_num, (paket, send_time, retransmit_count)(sent_packets.items()):
        եթե current_time - send_time > ack_timeout:
            եթե retransmit_count < max_retransmissions:
                packets_to_retransmit.append(seq_num)
            այլ:
                # փաթեթը վերջնականապես կորած է, MaxRetransmissions-ից հետո
                handle_packet_loss(seq_num)
                del sent_packets[seq_num]

    յուրաքանչյուր seq_num, որը կա packets_to_retransmit-ում:
        paket, _, retransmit_count = sent_packets[seq_num]
        send_udp(paket)
        sent_packets[seq_num] = (paket, time.time(), retransmit_count + 1) # թարմացում ժամանակի և հաշվիչի

Այս իրականացումը հիմնականում ստեղծում է UDP-ի վրա TCP-ի նման հուսալիություն ապահովող պրոտոկոլ։ կոնկրետ մոտեցումը կախված է հավելվածի պահանջներից (օրինակ՝ ուշացում, միջանցքային հզորություն): Բազմաթիվ դեպքերում, երբ պահանջվում է հուսալիություն, ավելի լավ է օգտագործել պատրաստի պրոտոկոլներ (TCP, QUIC) կամ փորձարկված գրադարաններ։