Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Kua huri te Ipurangi i te wa roa. Ko tetahi o nga tikanga matua o te Ipurangi - Ko te UDP e whakamahia ana e nga tono ehara i te mea ki te tuku i nga raraunga me nga panui, engari ki te whakarato hononga "hoa-ki-hoa" i waenga i nga pona whatunga. Na tana hoahoa ngawari, he maha nga whakamahinga o tenei kawa kaore i whakamaherehia i mua, engari, ko nga ngoikoretanga o te kawa, penei i te kore o te tuku whakamana, kaore i ngaro ki hea. Ko tenei tuhinga e whakaatu ana i te whakatinanatanga o te kawa tuku taurangi mo te UDP.
Ngā tirotiro:urunga
Nga Whakaritenga Kawa
Pane UDP pono
Ngā mātāpono whānui o te kawa
Nga waahi me nga kawa kawa
Hoahoa whenua tuku UDP pono
Hohonu atu ki te waehere. wae mana tuku
Hohonu atu ki te waehere. āhua

Hohonu atu ki te waehere. Te Waihanga me te Whakapumau Hononga
Hohonu atu ki te waehere. Katia te hononga i te wa mutunga
Hohonu atu ki te waehere. Te whakaora i te whakawhiti raraunga
API UDP pono
mutunga
Hononga whai hua me nga tuhinga

urunga

Ko te hoahoanga taketake o te Ipurangi i kii he mokowā wāhitau riterite kei roto i ia kōpuku he wāhitau IP o te ao me te ahurei, ka taea te korero tika ki etahi atu pona. Inaianei he rereke te hoahoanga o te Ipurangi - tetahi waahanga o nga wahitau IP o te ao me te maha o nga waahi me nga wahitau motuhake kei muri i nga taputapu NAT.I roto i tenei hoahoanga, ko nga taputapu anake i roto i te waahi waahi o te ao ka ngawari te korero ki tetahi i runga i te whatunga na te mea he wahitau IP ahurei to ratou, huri noa i te ao. Ka taea e te node i runga i te whatunga tūmataiti te hono ki etahi atu node i runga i te whatunga kotahi, ka taea hoki te hono atu ki etahi atu pona rongonui i roto i te waahi waahi o te ao. Ko te nuinga o tenei tauwhitinga i tutuki na te tikanga whakamaori wahitau whatunga. Ko nga taputapu NAT, penei i nga pouara Wi-Fi, ka waihanga i nga urunga ripanga whakamaori motuhake mo nga hononga putaatu me te whakarereke i nga wahitau IP me nga tau tauranga i roto i nga kete. Ma tenei ka taea nga hononga puta mai i te whatunga tūmataiti ki nga kaihautu i te waahi waahi o te ao. Engari i te wa ano, ko nga taputapu NAT te nuinga ka aukati i nga waka taumai katoa mena ka whakaritea nga ture motuhake mo nga hononga taumai.

He tika tenei hoahoanga o te Ipurangi mo te whakawhitiwhiti korero a te kiritaki-tūmau, ka taea e nga kiritaki te noho ki roto i nga whatunga tūmataiti, me nga kaitoro he wahitau o te ao. Engari he uaua ki te hono tika o nga pona e rua i waenga rerekē whatunga tūmataiti. He mea nui te hono tika i waenga i nga pona e rua mo nga tono hoa-ki-hoa penei i te tuku reo (Skype), te uru mamao ki te rorohiko (TeamViewer), te petipeti ipurangi ranei.

Ko tetahi o nga huarahi tino whai hua mo te whakarite hononga hoa-ki-hoa i waenga i nga taputapu i runga i nga whatunga motuhake rereke ka kiia ko te pupuhi poka. Ka whakamahia tenei tikanga me nga tono i runga i te kawa UDP.

Engari ki te hiahia to tono ki te tuku i nga raraunga, hei tauira, ka whakawhiti koe i nga konae i waenga i nga rorohiko, katahi ka raru te whakamahi i te UDP na te mea ehara te UDP i te kawa tuku taurangi me te kore e tuku i nga paakete kia rite ki te TCP. kawa.

I roto i tenei take, ki te whakarite i te tuku paatete whai mana, me whakatinana he kawa paparanga tono e whakarato ana i nga mahi e tika ana me te mahi i runga i te UDP.

Kei te pirangi au ki te mahara tonu kei reira he tikanga kuia poka TCP mo te whakatuu hononga TCP i waenga i nga pona i roto i nga momo whatunga motuhake, engari na te kore tautoko e te maha o nga taputapu NAT, kaore e kiia ko te huarahi matua ki te hono atu. taua pona.

Mo te toenga o tenei tuhinga, ka aro noa ahau ki te whakatinanatanga o te kawa tuku whakamana. Ko te whakatinanatanga o te tikanga kuki poka UDP ka whakaahuahia i roto i nga tuhinga e whai ake nei.

Nga Whakaritenga Kawa

  1. Ko te tuku putea pono i whakatinanahia na roto i te tikanga urupare pai (te mea e kiia nei he mihi pai)
  2. Ko te hiahia mo te whakawhiti pai o nga raraunga nui, i.e. me karo te kawa i te tukunga o nga paakete kore e tika
  3. Ka taea te whakakore i te tikanga whakapumau tuku (te kaha ki te mahi hei kawa UDP "parakore")
  4. Te kaha ki te whakatinana i te aratau whakahau, me te whakapumautanga o ia karere
  5. Ko te waahanga taketake o te whakawhiti raraunga i runga i te kawa me he karere

Ko enei whakaritenga ka tino rite ki nga whakaritenga Kawa Raraunga Whakapono kua whakaahuatia i roto RFC 908 и RFC 1151, a i whakawhirinaki ahau ki aua paerewa i te wa e whakawhanake ana i tenei kawa.

Kia mohio ai ki enei whakaritenga, me titiro ki te wa whakawhiti raraunga i waenga i nga waahanga whatunga e rua ma te whakamahi i nga tikanga TCP me te UDP. Kia rua nga keehi ka ngaro tetahi kete.
Te whakawhiti i nga raraunga tauwhitiwhiti kore i runga i te TCP:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Ka kitea e koe mai i te hoahoa, mena kua ngaro te paatete, ka kitea e TCP te kete kua ngaro, ka ripoata ki te kaituku ma te tono mo te maha o te wahanga ngaro.
Te whakawhiti raraunga ma te kawa UDP:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Karekau a UDP e whai i nga mahi rapunga mate. Ko te whakahaere i nga hapa tuku i roto i te kawa UDP te kawenga katoa o te tono.

Ka kitea te hapa i roto i te kawa TCP ma te whakatu hononga ki te node mutunga, te penapena i te ahua o taua hononga, me te tohu i te maha o nga paita ka tukuna ki ia pane pane, me te whakamohio i nga rihīti ma te whakamahi i te nama mihi.

I tua atu, ki te whakapai ake i te mahi (ara te tuku neke atu i te kotahi waahanga me te kore e whiwhi mihi), ka whakamahia e te kawa TCP te matapihi whakawhiti e kiia nei - ko te maha o nga paita o nga raraunga e tumanakohia ana e te kaituku o te wahanga kia whiwhi.

Mo etahi atu korero mo te kawa TCP, tirohia RFC 793, mai i te UDP ki RFC 768kei hea, i roto i te meka, kua tautuhia.

Mai i nga korero o runga ake nei, ka maarama ko te hanga i tetahi kawa tuku karere pono i runga i te UDP (ka kiia i muri nei ko UDP pono), e hiahiatia ana ki te whakatinana i nga tikanga whakawhiti raraunga e rite ana ki te TCP. Ara:

  • tiakina te ahua hononga
  • whakamahia te tatau wahanga
  • whakamahi i nga kohinga whakapumau motuhake
  • te whakamahi i te tikanga matapihi ngawari ki te whakapiki ake i te puta kawa

Hei taapiri, me hiahia koe:

  • tohu te timatanga o te karere, ki te toha rauemi mo te hononga
  • tohu te mutunga o te karere, ki te tuku i te karere kua tae ki te tono whakarunga me te tuku rauemi kawa
  • tukua te kawa hononga-motuhake ki te whakakore i te tikanga whakau tuku kia mahi hei UDP "parakore".

Pane UDP pono

Kia maumahara ko te UDP raraunga kua whakauruhia ki roto i te IP raraunga. E tika ana te "takai" te paakete UDP Whakapono ki roto i te mahere raraunga UDP.
Whakakapinga pane UDP pono:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

He tino ngawari te hanganga o te pane UDP Whakapono:

Te whakatinanatanga o te kawa Udp Whakapono mo .Net

  • Kara - haki mana mōkihi
  • Momo Karere - momo karere e whakamahia ana e nga tono whakarunga hei ohauru ki nga karere motuhake
  • TransmissionId - te tau o te tuku, me te wahitau me te tauranga o te kaiwhiwhi, he tohu motuhake te hononga
  • PacketNumber - tau packet
  • Kōwhiringa - kōwhiringa kawa taapiri. Mo te putea tuatahi, ka whakamahia hei tohu i te rahi o te karere

Ko nga haki e whai ake nei:

  • FirstPacket - te kete tuatahi o te karere
  • NoAsk - karekau te karere e hiahia kia whakahoehia he tikanga mihi
  • LastPacket - te kete whakamutunga o te karere
  • RequestForPacket - mokete whakau, tono ranei mo te kete kua ngaro

Ngā mātāpono whānui o te kawa

I te mea ko te UDP Whakapono e aro ana ki te tuku karere pono i waenga i nga pona e rua, me kaha ki te whakatu hononga ki tera taha. Hei whakarite hononga, ka tukuna e te kaituku he paatete me te haki FirstPacket, ko te whakautu ki te mea ka whakapumautia te hononga. Ko nga putea whakautu katoa, me etahi atu kupu, ko nga putea mihi, ka tautuhi i nga wa katoa te uara o te mara PacketNumber ma te kotahi neke atu i te uara PacketNumber nui rawa atu o nga paatete kua whiwhi angitu. Ko te mara Kōwhiringa mo te pākete tuatahi i tukuna ko te rahi o te karere.

Ka whakamahia he tikanga rite ki te whakamutu i tetahi hononga. Kua whakaritea te haki LastPacket ki te kete whakamutunga o te karere. I roto i te kete whakautu, ka tohuhia te nama o te paatete whakamutunga + 1, ko te tikanga mo te taha tango te tikanga o te tukunga o te karere.
Te whakatu hononga me te hoahoa whakamutu:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Ina oti te hononga, ka timata te whakawhiti raraunga. Ka tukuna nga raraunga ki nga poraka o nga paatete. Kei ia poraka, haunga te mea whakamutunga, he maha nga paatete. He rite ki te rahinga matapihi whiwhi/tuku. He iti ake pea nga putea o te paraka raraunga whakamutunga. I muri i te tuku i ia poraka, ka tatari te taha tuku mo te whakapumautanga tuku, he tono ranei kia tukuna ano nga paatete ngaro, ka waiho te matapihi whiwhi/tuku kia tuwhera ki te whiwhi whakautu. I muri i te whakapumautanga o te tuku poraka, ka huri te matapihi whiwhi / tuku ka tukuna te poraka o muri mai.

Ka whiwhi te taha tango i nga paatete. Ka takina ia kete ki te kite mena ka taka ki roto i te matapihi tuku. Ko nga paatete me nga taarua kaore e taka ki te matapihi ka tātarihia. No te mea Mena kua whakatauhia te rahi o te matapihi me te rite mo te kaiwhiwhi me te kaituku, na i te mea ka tukuna he poraka o nga putea kaore he ngaro, ka nekehia te matapihi ki te tango i nga paanui o te poraka o muri o nga raraunga me te whakapumautanga tuku. tukuna. Mena karekau te matapihi e whakakiia i roto i te waa i whakaritea e te kaima mahi, katahi ka timata te haki kaore ano kia tukuna mai nga kete ka tukuna ano nga tono mo te tuku.
Hoahoa Whakawhiti Anō:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Nga waahi me nga kawa kawa

He maha nga take kaore e taea te whakatuu hononga. Hei tauira, mena kei te tuimotu te roopu whiwhi. I tenei keehi, i te wa e ngana ana ki te whakatu hononga, ka kati te hononga i te wa mutunga. Ko te whakatinanatanga UDP Whakapono e whakamahi ana i nga taima e rua hei whakarite i nga waahi. Ko te tuatahi, ko te taima mahi, ka whakamahia hei tatari mo te whakautu mai i te kaihautu mamao. Mena ka pupuhi ki te taha o te kaituku, ka tukuna ano te paakete whakamutunga. Mena ka pau te taima ki te kaiwhiwhi, ka mahia he haki mo nga paatete ngaro ka tukuna nga tono mo te tuku ano.

Ko te taima tuarua e hiahiatia ana hei kati i te hononga mena he kore korero i waenga i nga pona. Mo te taha kaituku, ka timata i muri tonu i te paunga o te wa mahi, me te tatari mo te whakautu mai i te pona mamao. Mena karekau he whakautu i roto i te waa kua tohua, ka mutu te hononga ka tukuna nga rauemi. Mo te taha whiwhi, ka timata te matama kati hononga i muri i te paunga o te taima mahi e rua nga wa. He mea tika tenei hei inihua i te ngaro o te kete whakau. Ka pau te taima, ka mutu ano te hononga ka tukuna nga rauemi.

Hoahoa whenua tuku UDP pono

Ka whakatinanahia nga maataapono o te kawa i roto i te miihini ahua mutunga, ko ia kawanatanga te kawenga mo tetahi arorau o te tukatuka putea.
Hoahoa State UDP pono:

Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Katia - ehara i te mea he whenua, he timatanga me te mutunga mo te miihini. Mo te kawanatanga Katia ka riro mai he poraka mana tuku, ma te whakamahi i te tūmau UDP tukutahi, ka tuku atu i nga paakete ki nga hononga e tika ana, ka timata i te tukatuka kawanatanga.

TuatahiPacketTukua – te ahua tuatahi kei roto te hononga puta i te wa ka tukuna te karere.

I roto i tenei ahua, ka tukuna te putea tuatahi mo nga karere noa. Mo nga karere karekau he whakapumautanga tuku, koinei anake te whenua ka tukuna te katoa o nga korero.

Huringa Tukunga – te ahua whenua mo te tuku i nga paanui karere.

Te whakawhiti ki a ia mai i te kawanatanga TuatahiPacketTukua ka mahia i muri i te tukunga o te kete tuatahi o te karere. I roto i tenei ahuatanga ka tae mai nga mihi me nga tono mo te tuku ano. Ka taea te puta mai i roto i nga keehi e rua - mena ka angitu te tuku o te karere, ma te wa poto ranei.

Peeke Tuatahi Kua riro – te ahua tuatahi mo te kaiwhiwhi o te karere.

Ka tirotirohia te tika o te timatanga o te tuku, ka hangaia nga hanganga e tika ana, ka tukuna he mihi mo te whiwhinga o te kete tuatahi.

Mo te panui kei roto i te paatete kotahi ka tukuna me te kore e whakamahi tohu o te tuku, koinei anake te kawanatanga. I muri i te tukatuka i taua karere, ka kati te hononga.

Huihuinga – te ahua taketake mo te whiwhi putea karere.

Ka tuhia e ia nga paatete ki te rokiroki rangitahi, ka tirohia mo te ngaronga o te paatete, ka tuku mihi mo te tukunga o te poraka o nga paanui me te katoa o te karere, ka tuku tono mo te tuku ano i nga paanui kua ngaro. Mena ka angitu te whiwhinga o te panui katoa, ka uru te hononga ki te kawanatanga oti, ki te kore, ka puta he waahi.

oti – katia te hononga i te mea ka angitu te whiwhinga o te karere katoa.

He mea tika tenei ahua mo te huihuinga o te karere me te keehi i te wa i ngaro ai te whakapumautanga tuku o te karere i te huarahi ki te kaituku. Ka puta tenei ahua ma te waahi, engari ka kiia te hononga kua katia pai.

Hohonu atu ki te waehere. wae mana tuku

Ko tetahi o nga mea matua o te UDP Whakapono ko te poraka mana tuku. Ko te mahi o tenei poraka ko te penapena i nga hononga o naianei me nga huānga awhina, te tohatoha i nga paatete taumai ki nga hononga e tika ana, te whakarato i tetahi atanga mo te tuku paatete ki tetahi hononga, me te whakatinana i te API kawa. Ka whiwhi te poraka mana tuku i nga paatete mai i te paparanga UDP ka tukuna atu ki te miihini kawanatanga mo te tukatuka. Hei tango i nga paatete, ka whakamahia he tūmau UDP tukutahi.
Ko etahi mema o te akomanga 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;    	
  //...
}

Te whakatinanatanga o te tūmau UDP tukutahi:

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

Mo ia whakawhitinga karere, ka hangaia he hanganga kei roto nga korero mo te hononga. Ko taua hanganga ka kiia rekoata hononga.
Ko etahi mema o te akomanga 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;
  //...
}

Hohonu atu ki te waehere. āhua

Ka whakatinanahia e nga whenua te miihini kawanatanga o te kawa UDP Whakapono, kei reira te tukatuka matua o nga paatete. Ko te akomanga waitara ReliableUdpState he atanga mo te kawanatanga:

Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Ko te arorau katoa o te kawa ka whakatinanahia e nga karaehe kua whakaatuhia i runga ake nei, me tetahi akomanga awhina e whakarato ana i nga tikanga tuuturu, penei, hei tauira, te hanga i te pane ReliableUdp mai i te rekoata hononga.

I muri mai, ka whakaarohia e maatau te whakatinanatanga o nga tikanga atanga e whakatau ana i nga algorithms taketake o te kawa.

Tikanga DisposeByTimeout

Ko te tikanga DisposeByTimeout te kawenga mo te tuku rauemi hononga i muri i te waahi me te tohu i te tuku karere angitu/kore.
ReliableUdpState.DisposeByTimeout:

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

Ka whakakorea noa i te kawanatanga oti.
Kua oti.DisposeByTimeout:

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

Tikanga ProcessPackets

Ko te tikanga ProcessPackets te kawenga mo te tukatuka taapiri o tetahi kete, kete ranei. Ka waea tika mai, ma te paatata tatari ranei.

Taea Huihuinga kua whakakorehia te tikanga me te kawenga mo te tirotiro mo nga putea ngaro me te whakawhiti ki te kawanatanga oti, i te mea ka riro mai te kete whakamutunga ka tukuna he haki angitu
Huihuinga.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);
  }
}

Taea Huringa Tukunga ka karangahia tenei tikanga i runga i te matawā anake, a ko te kawenga mo te tuku ano i te karere whakamutunga, me te whakaahei i te taima kati hononga.
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);
}

Taea oti ko te tikanga ka mutu te mahi oma me te tuku i te karere ki nga kaiohauru.
Kua oti.ProcessPackets:

public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
  if (connectionRecord.WaitForPacketsTimer != null)
    connectionRecord.WaitForPacketsTimer.Dispose();
  // собираем сообщение и передаем его подписчикам
  ReliableUdpStateTools.CreateMessageFromMemoryStream(connectionRecord);
}

ReceivePacket Tikanga

Taea Peeke Tuatahi Kua riro Ko te mahi matua o te tikanga ko te whakatau mena kua tae mai te paanui karere tuatahi ki te atanga, me te kohi karere kei roto i te kete kotahi.
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);
  }
}

Taea Huringa Tukunga kua whakakorehia tenei tikanga ki te whakaae ki nga mihi tuku me nga tono tuku ano.
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));
}

Taea Huihuinga i roto i te tikanga ReceivePacket, ko te mahi matua o te whakahiato i te karere mai i nga paatete taumai ka puta.
Huihuinga.ReceivePacket:

public override void ReceivePacket(ReliableUdpConnectionRecord connectionRecord, ReliableUdpHeader header, byte[] payload)
{
  if (connectionRecord.IsDone != 0)
    return;
  // обработка пакетов с отключенным механизмом подтверждения доставки
  if (header.Flags.HasFlag(ReliableUdpHeaderFlags.NoAsk))
  {
    // сбрасываем таймер
    connectionRecord.CloseWaitTimer.Change(connectionRecord.LongTimerPeriod, -1);
    // записываем данные
    ReliableUdpStateTools.WritePacketData(connectionRecord, header, payload);
    // если получили пакет с последним флагом - делаем завершаем          
    if (header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
    {
      connectionRecord.State = connectionRecord.Tcb.States.Completed;
      connectionRecord.State.ProcessPackets(connectionRecord);
    }
    return;
  }        
  // расчет конечной границы окна
  int windowHighestBound = Math.Min((connectionRecord.WindowLowerBound + connectionRecord.WindowSize - 1), (connectionRecord.NumberOfPackets - 1));
  // отбрасываем не попадающие в окно пакеты
  if (header.PacketNumber < connectionRecord.WindowLowerBound || header.PacketNumber > (windowHighestBound))
    return;
  // отбрасываем дубликаты
  if (connectionRecord.WindowControlArray.Contains(header.PacketNumber))
    return;
  // записываем данные 
  ReliableUdpStateTools.WritePacketData(connectionRecord, header, payload);
  // увеличиваем счетчик пакетов        
  connectionRecord.PacketCounter++;
  // записываем в массив управления окном текущий номер пакета        
  connectionRecord.WindowControlArray[header.PacketNumber - connectionRecord.WindowLowerBound] = header.PacketNumber;
  // устанавливаем наибольший пришедший пакет        
  if (header.PacketNumber > connectionRecord.RcvCurrent)
    connectionRecord.RcvCurrent = header.PacketNumber;
  // перезапускам таймеры        
  connectionRecord.TimerSecondTry = false;
  connectionRecord.WaitForPacketsTimer.Change(connectionRecord.ShortTimerPeriod, -1);
  if (connectionRecord.CloseWaitTimer != null)
    connectionRecord.CloseWaitTimer.Change(-1, -1);
  // если пришел последний пакет
  if (header.Flags.HasFlag(ReliableUdpHeaderFlags.LastPacket))
  {
    Interlocked.Increment(ref connectionRecord.IsLastPacketReceived);
  }
  // если нам пришли все пакеты окна, то сбрасываем счетчик
  // и высылаем пакет подтверждение
  else if (connectionRecord.PacketCounter == connectionRecord.WindowSize)
  {
    // сбрасываем счетчик.      
    connectionRecord.PacketCounter = 0;
    // сдвинули окно передачи
    connectionRecord.WindowLowerBound += connectionRecord.WindowSize;
    // обнуление массива управления передачей
    connectionRecord.WindowControlArray.Nullify();
    ReliableUdpStateTools.SendAcknowledgePacket(connectionRecord);
  }
  // если последний пакет уже имеется        
  if (Thread.VolatileRead(ref connectionRecord.IsLastPacketReceived) != 0)
  {
    // проверяем пакеты          
    ProcessPackets(connectionRecord);
  }
}

Taea oti Ko te mahi anake o te tikanga ko te tuku mihi ano mo te tukunga angitu o te karere.
Kua oti.ReceivePacket:

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

Tukua Tikanga Pakete

Taea TuatahiPacketTukua ka tukuna e tenei tikanga te putea tuatahi o nga raraunga, ki te kore e hiahiatia e te karere te whakapumautanga tuku, ko te karere katoa.
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);
}

Taea Huringa Tukunga i tenei tikanga, ka tukuna he poraka o nga paatete.
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 );
  }
}

Hohonu atu ki te waehere. Te Waihanga me te Whakapumau Hononga

Inaianei kua kite tatou i nga ahuatanga taketake me nga tikanga e whakamahia ana ki te hapai i nga kawanatanga, me wehewehe etahi tauira mo te mahi a te kawa i roto i nga korero taipitopito.
Hoahoa tuku raraunga i raro i nga tikanga noa:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Whakaarohia nga korero mo te hanganga rekoata hononga ki te hono me te tuku i te kete tuatahi. Ko te whakawhitinga i nga wa katoa ka timatahia e te tono e karanga ana i te API karere tuku. I muri mai, ka karangahia te tikanga StartTransmission o te poraka mana tuku, ka timata te tuku raraunga mo te karere hou.
Te hanga hononga putaatu:

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

Te tuku i te kete tuatahi (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);
}

I muri i te tuku i te putea tuatahi, ka uru te kaituku ki te kawanatanga Huringa Tukunga – tatari mo te whakapumautanga o te tuku kete.
Ko te taha tango, ma te whakamahi i te tikanga EndReceive, ka whiwhi i te kete kua tukuna, ka hanga he hou rekoata hononga ka tukuna tenei kete, me te pane kua oti te whakamaarama, ki te tikanga ReceivePacket o te kawanatanga mo te tukatuka Peeke Tuatahi Kua riro
Te hanga hononga ki te taha whiwhi:

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

Te whiwhi i te kete tuatahi me te tuku mihi (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);
  }
}

Hohonu atu ki te waehere. Katia te hononga i te wa mutunga

Ko te whakahaere i te wa poto he waahanga nui o te UDP Whakapono. Whakaarohia he tauira i rahua ai te node takawaenga, ka kore e taea te tuku raraunga ki nga taha e rua.
Hoahoa mo te kati i tetahi hononga ma te waahi:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Ka kitea mai i te hoahoa, ka timata te matama mahi a te kaituku i muri tonu i te tuku i tetahi poraka o nga paatete. Ka tupu tenei i roto i te tikanga SendPacket o te kawanatanga Huringa Tukunga.
Whakahohe ana i te taima mahi (te ahua o teSendingCycle):

public override void SendPacket(ReliableUdpConnectionRecord connectionRecord)
{      
  // отправляем блок пакетов   
  // ...   
  // перезапускаем таймер после отправки
  connectionRecord.WaitForPacketsTimer.Change( connectionRecord.ShortTimerPeriod, -1 );
  if ( connectionRecord.CloseWaitTimer != null )
    connectionRecord.CloseWaitTimer.Change( -1, -1 );
}

Ka whakatauhia nga taima ka hangaia te hononga. Ko te ShortTimerPeriod taunoa he 5 hēkona. I roto i te tauira, kua whakaritea ki te 1,5 hēkona.

Mo te hononga taumai, ka timata te taima i muri i te whiwhinga o te kete raraunga taumai whakamutunga, ka puta tenei i roto i te tikanga ReceivePacket o te kawanatanga. Huihuinga
Whakahohe ana i te taima mahi (Te ahua Huihuinga):

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

Karekau he kete i tae mai i te hononga taumai i te wa e tatari ana mo te taima mahi. Ka pahemo te taima ka karangahia te tikanga ProcessPackets, i kitea ai nga paatete ngaro ka tukuna ano nga tono tuku mo te wa tuatahi.
Te tuku tono tuku ano (Te ahua Huihuinga):

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

Kua tautuhia te taurangi TimerSecondTry ki pono. Ko tenei taurangi te kawenga mo te whakaara ano i te taima mahi.

I te taha o te kaituku, ka puta ano te matama mahi, ka tukuna ano te paakete whakamutunga.
Whakahohe ana i te taima kati hononga (te ahua o teSendingCycle):

public override void ProcessPackets(ReliableUdpConnectionRecord connectionRecord)
{
  // ...        
  // отправляем повторно последний пакет 
  // ...        
  // включаем таймер CloseWait – для ожидания восстановления соединения или его завершения
  StartCloseWaitTimer(connectionRecord);
}

I muri i tera, ka timata te matama kati hononga i te hononga putaatu.
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);
}

He 30 hēkona te taunoa o te wā kati matawā hononga.

Whai muri i te wa poto, ka mura ano te kaima mahi i te taha o te kaiwhiwhi, ka tukuna ano nga tono, ka mutu ka tiimata te wa kati hononga mo te hononga taumai

Ka pa ana nga taima kati, ka tukuna nga rauemi katoa o nga rekoata hononga e rua. Ka whakaatu te kaituku i te kore tuku ki te tono whakarunga (tirohia API UDP pono).
Te tuku rauemi rekoata hononga:

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

Hohonu atu ki te waehere. Te whakaora i te whakawhiti raraunga

Hoahoa whakaora tuku raraunga mena ka ngaro te kete:Te whakatinanatanga o te kawa Udp Whakapono mo .Net

Ka rite ki te korero kua korerohia mo te kati i te hononga i te wa mutunga, ka pau te wa mahi, ka tirohia e te kaiwhiwhi mo nga putea kua ngaro. Mena kua ngaro te kete, ka whakahiatohia he rarangi o te maha o nga paakete kaore i tae ki te kaiwhiwhi. Ka whakauruhia enei nama ki roto i te rarangi LostPackets o tetahi hononga motuhake, ka tukuna nga tono mo te tuku ano.
Te tuku tono ki te tuku ano i nga kete (Te ahua Huihuinga):

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

Ka whakaae te kaituku i te tono tuku ano ka tukuna atu nga paakete kua ngaro. He mea tika kia mohio koe i tenei wa kua timata te kaituku i te wa kati hononga, a, ka tae mai he tono, ka tautuhi ano.
Te tuku ano i nga kete kua ngaro (te ahua o teSendingCycle):

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

Ko te paatete riri (pakete #3 kei te hoahoa) ka riro mai i te hononga taumai. Ka mahia he haki ki te kite mena kua ki tonu te matapihi whiwhinga ka whakahokia mai ano te tuku raraunga.
Te tirotiro mo nga patu i te matapihi whiwhi (te ahua Huihuinga):

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

API UDP pono

Ki te taunekeneke ki te kawa whakawhiti raraunga, kei reira he akomanga Udp Whakapono tuwhera, he takai i runga i te poraka mana whakawhiti. Anei nga mema tino nui o te akomanga:

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

Ka riro nga karere ma te ohaurunga. Tukua te waitohu mo te aratuka hoki:

public delegate void ReliableUdpMessageCallback( ReliableUdpMessage reliableUdpMessage, IPEndPoint remoteClient );

Karere:

public class ReliableUdpMessage
{
  // тип сообщения, простое перечисление
  public ReliableUdpMessageTypes Type { get; private set; }
  // данные сообщения
  public byte[] Body { get; private set; }
  // если установлено в true – механизм подтверждения доставки будет отключен
  // для передачи конкретного сообщения
  public bool NoAsk { get; private set; }
}

Hei ohauru ki tetahi momo karere motuhake me/ranei tetahi kaituku motuhake, ka whakamahia nga tawhā e rua: ReliableUdpMessageTypes messageType me IPEndPoint ipEndPoint.

Momo Karere:

public enum ReliableUdpMessageTypes : short
{ 
  // Любое
  Any = 0,
  // Запрос к STUN server 
  StunRequest = 1,
  // Ответ от STUN server
  StunResponse = 2,
  // Передача файла
  FileTransfer =3,
  // ...
}

Ka tukuna te karere i te tukutahi; mo tenei, ka whakatinanahia e te kawa he tauira hotaka tukutahi:

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

Ko te hua o te tuku karere ka pono - mena kua tutuki pai te karere ki te kaiwhiwhi me te teka - mena ka kati te hononga i te wa mutunga:

public bool EndSendMessage(IAsyncResult asyncResult)

mutunga

He maha nga korero kaore i te korerohia i tenei tuhinga. Nga tikanga orite miro, otahi me te whakahaere hapa, te whakatinanatanga o nga tikanga tuku karere tukutahi. Engari ko te kaupapa matua o te kawa, ko te whakamaarama mo te arorau mo te tukatuka i nga paatete, te whakatu hononga, me te whakahaere i nga waahi, me marama ki a koe.

Ko te putanga whakaatu o te kawa tuku pono he pakari, he ngawari hoki ki te whakatutuki i nga whakaritenga kua tautuhia i mua. Engari e hiahia ana ahau ki te taapiri ka taea te whakapai ake te whakatinanatanga kua whakaahuatia. Hei tauira, ki te whakanui ake i te urunga me te huri whakahihiri i nga wa taima, ka taea te taapiri i nga tikanga penei i te matapihi reti me te RTT ki te kawa, ka whai hua ano ki te whakatinana i tetahi tikanga mo te whakatau MTU i waenga i nga pona hononga (engari mena ka tukuna nga karere nui) .

He mihi nui ki a koe mo to whakaaro, ka tatari ahau ki o korero me o korero.

PS Mo te hunga e hiahia ana ki nga korero, e hiahia ana ranei ki te whakamatautau i te kawa, te hono ki te kaupapa i runga i GitHube:
Kaupapa UDP pono

Hononga whai hua me nga tuhinga

  1. Whakatakotoranga kawa TCP: i roto i te Ingarihi и i Rusia
  2. Whakatakotoranga kawa UDP: i roto i te Ingarihi и i Rusia
  3. Matapaki mo te kawa RUDP: tauira-ietf-signtran-reliable-udp-00
  4. Kawa Raraunga Whakapono: RFC 908 и RFC 1151
  5. He whakatinanatanga ngawari o te whakapumautanga tuku mo te UDP: Tangohia Mana Tapeke o To Whatunga Ki te .NET Me te UDP
  6. Tuhinga e whakaahua ana i nga tikanga whakawhiti NAT: Whakawhitiwhiti Hoa-ki-Hoa puta noa i nga Kaiwhakamaori Wāhitau Whatunga
  7. Te whakatinanatanga o te tauira hötaka tukutahi: Te whakatinana i te Tauira Papatono Asynchronous CLR и Me pehea te whakatinana i te tauira hoahoa IAsyncResult
  8. Te kawe i te tauira hotaka tukutahi ki te tauira tukutahi-mahi (APM i TAP):
    TPL me te .NET Asynchronous Papatononga Tuku iho
    Whakawhitiwhiti me etahi atu Tauira Tukutahi me nga Momo

Whakahōu: Tēnā koe mayorovp и sidristij mo te whakaaro ki te taapiri i tetahi mahi ki te atanga. Ko te hototahi o te whare pukapuka me nga punaha whakahaere tawhito kaore i te takahia, no te mea Ko te anga 4 e tautoko ana i te XP me te 2003 tūmau.

Source: will.com

Tāpiri i te kōrero