Programavimas

„Java“ patarimas 18: „JDK 1.0.2 DatagramSocket“ skirtojo laiko funkcijos įdiegimas

Jei sukūrėte „Java“ programą, kuri naudoja „Datagram“ lizdą pranešimams siųsti ir gauti, gali tekti įdiegti skirtojo laiko funkciją norint atblokuoti „DatagramSocket“ gauti metodą. Be skirtojo laiko funkcijos jūsų programa blokuos, kol gaus pranešimą, o kadangi „Datagram“ pristatymas nėra garantuotas, jūsų programa gali užblokuoti tikrai ilgai. Šiame „Java“ patarime bus aprašyta „Windows“ laiko praleidimo ir atblokavimo technika „DatagramSocket“ gauti metodą.

Jūs tikriausiai jau spėjote, kad ši technika naudos siūlus. Siūlų programavimas „Java“ yra gana malonus. Galima būtų palyginti su slidinėjimo prie Tahoe ežero ar plaukimo šalia Santa Kruzo pakrantės džiaugsmais. (Gerai, gal taip nėra kad malonu, bet vis tiek labai smagu!)

Galvojant apie skirtojo laiko funkciją, turbūt pirmoji ir akivaizdžiausia mintis yra įdėti „DatagramSocket“ priėmimo funkciją į atskirą giją ir paleisti dar vieną giją kaip laikmatį, kuris pasibaigus gali užmušti priėmimą. siūlas, jei jis vis dar gyvas. Nors šis metodas veiks, jis tikriausiai nėra pats grakštiausias būdas atlikti užduotį.

Užuot nužudęs giją, kuri užblokuota gavimo metodo, norėjau grakštesnio sprendimo - tokio, kuris atblokuotų gavimo būdą. Norint tai pasiekti, man reikėjo gijos, kuri sugebėtų nusiųsti datagramos pranešimą į priimančią giją, kad atblokuotų gavimo giją, pasibaigus skirtam laikui. Taikomojo laiko gija įgyvendinama kaip savo klasė, o gavimo gija sukuria skirtojo laiko egzempliorių prieš blokuodama gavimo metodą. Šis kodas rodo skirtojo laiko klasės įgyvendinimą. Atminkite, kad dėl trumpumo išimčių tvarkymas praleidžiamas.

importuoti java.io. *; importuoti java.net. *; importuoti java.lang. *; viešoji klasė „DatagramWatchdogTimer“ įgyvendina „Runnable“ {DatagramWatchdogTimer (int timeoutSeconds) meta „SocketException“ {timeout = timeoutSeconds; lizdas = naujas DatagramSocket (); datagramPort = socket.getLocalPort (); Siūlai thisThread = nauja gija (tai); thisThread.start (); } public int getPort () {return datagramPort; } public void run () {// sukurkite standartinį atsakymo pranešimą, nurodantį, kad // pranešimas atėjo iš „DatagramWatchdogTimer“ // mano atveju pakanka nulio. String responseStr = naujas sveikasis skaičius (0) .toString (); baitas [] atsakymasBuf = naujas baitas [atsakymoStr.length ()]; answerStr.getBytes (0, answerStr.length (), answerBuff, 0); int atsakymo ilgis = atsakymasStr.length (); // gauti pranešimą iš gavimo gijos. // tai yra būtina, kad žinotume, kaip atgalinį pranešimą // išsiųsti atgal. baitas [] buferis = naujas užpakalis [128]; „DatagramPacket“ paketas = naujas „DatagramPacket“ (buferis, buferis.length); lizdas. gauti (paketas); // palaukite skirtojo laiko sekundės skaičių ir tada išsiųskite atblokuojantį // pranešimą. Sriegis.miega (skirtasis laikas * 1000); int requestorPort = packet.getPort (); „InetAddress“ requestorAddress = packet.getAddress (); DatagramPacket sendPacket = naujas DatagramPacket (atsakymasBuff, atsakymo ilgis, requestorAddress, requestorPort); DatagramSocket sendSocket = naujas DatagramSocket (); sendSocket.send (sendPacket); } private int timeout; private int datagramPort; privatus „DatagramSocket“ lizdas; } 

Kaip minėta pirmiau, kai tik jūsų programai reikia gauti datagramos pranešimą, ji gali sukurti „DatagramWatchdogTimer“ klasėje nustatyti pertraukos laikotarpį. Jei programa negauna tikro pranešimo per skirtingas sekundes, ji bus atblokuota gavus atblokavimo pranešimą iš „DatagramWatchdogTimer“ klasė.

Štai pavyzdys:

// programos kodas int timeoutSeconds = 5; InetAddress myAddress = InetAddress.getByName (""); // sukurti laikmačio klasės „DatagramWatchdogTimer“ egzempliorių wdTimer = new DatagramWatchdogTimer (timeoutSeconds); int wdPort = wdTimer.getPort (); // išsiųskite pranešimą į „wdTimer“, kad paleistumėte laikmatį // msgBuff gali būti viskas, ko norite. String msgString = nauja eilutė („laikas mane“); baitas [] msgBuff = naujas baitas [msgString.length ()]; msgString.getBytes (0, msgString.length (), msgBuff, 0); „DatagramSocket“ lizdas = naujas „DatagramSocket“ (); DatagramPacket wdPacket = nauja DatagramPacket (msgBuff, msgLength, myAddress, wdPort); socket.send (wdPacket); // dabar galite perskaityti iš lizdo ir turėti tam tikrą patikinimą //, kad blokuosite tik timeoutSeconds. baitas [] buferis = naujas baitas [1024]; „DatagramPacket“ paketas = naujas „DatagramPacket“ (buferis, buferis.length); lizdas. gauti (paketas); if (myAddress.equals (packet.getAddress) == true) {// gavo pranešimą iš laikmačio objekto} else {// gavo tikrą pranešimą} 

Naudodami šią techniką, būtinai naudokite tą patį „DatagramSocket“ tiek siunčiant į objektą „DatagramWatchdogTimer“, tiek gaunant datagramas. Tai užtikrina, kad objektas DatagramWatchdogTimer žino, kur siųsti atblokavimo pranešimą. Be to, aukščiau pateiktame pavyzdiniame kode buvo naudojamas dinamiškai paskirstytas prievadas, be jokių argumentų ištaisant „DatagramSocket“ (). Jis taip pat veiktų naudodamas gerai žinomą jūsų pasirinktą prievadą, pvz., „DatagramSocket“ (8000). Galiausiai, galbūt norėsite, kad laikmačio objektas atsiųstų daugiau nei vieną atblokavimo pranešimą, kad tik padidintumėte tikimybę, jog programa jį gaus. Tai neturėtų kelti problemų, nes laikmačio objektas veikia kaip gija toje pačioje mašinoje kaip ir programa.

Albertas Lopezas buvo „Sun Microsystems“ techninio personalo narys nuo 1989 iki 1995 m. Neseniai jis prisijungė prie Informacinių sistemų personalo Čikagos prekybos taryboje, kur yra pagrindinis „Java“ kūrimo komandos, kuriančios naujos kartos, narys. elektroninė prekybos sistema naudojant „Java“.

Šią istoriją „Java 18 patarimas:„ JDK 1.0.2 DatagramSocket “skirtojo laiko funkcijos naudojimas“ iš pradžių paskelbė „JavaWorld“.