Kapag pinag-uusapan natin ang networking, hindi natin mabibigo na banggitin ang modelo ng OSI.

Sa mga tuntunin ng modelong ito, ngayon kami ay pinaka-interesado sa layer ng transportasyon (4).

Ito ang antas kung saan nagtatrabaho kami sa paglipat ng data "mula sa punto A hanggang sa punto B." Ang pangunahing gawain ng layer ng transportasyon ay upang matiyak na ang isang mensahe ay naihatid sa patutunguhan, habang pinapanatili ang tamang pagkakasunud-sunod. Ang dalawang pinakakaraniwang transport layer protocol ay: TCP at UDP. Gumagana sila sa konsepto sa iba't ibang paraan, ngunit ang bawat isa ay may sariling mga pakinabang na nagpapahintulot sa kanila na malutas ang mga partikular na problema.

Una, tingnan natin kung paano gumagana ang TCP.

Ang TCP (Transmission Control Protocol) ay isang network protocol na nagsisiguro na ang isang koneksyon sa pagitan ng mga host ay naitatag bago ang palitan ng data.

Ito ay isang napaka-maaasahang protocol, dahil sa tuwing nagpapadala ito ng isa pang data packet, dapat itong suriin kung ang nakaraang packet ay natanggap.

Ang mga ipinadalang packet ay iniutos, at kung may mga problema sa isang partikular na packet (ibig sabihin, hindi kinukumpirma ng tumatanggap na partido na dumating na ang packet), pagkatapos ay ipapadala muli ang packet. Bilang resulta, ang rate ng paglipat ay medyo mababa, dahil mas maraming oras ang kinakailangan para sa mahigpit na pagsubaybay at para sa pagtiyak ng tamang pag-order.

Dito pumapasok ang "kapatid" nito, ang UDP protocol. Hindi tulad ng TCP, walang pakialam ang UDP sa kaayusan at katayuan ng bawat packet. Nagpapadala lamang ito ng data nang walang kumpirmasyon sa paghahatid. Higit pa rito, hindi ito nagtatag ng koneksyon at hindi nakadepende sa status ng koneksyon sa anumang paraan.

Ang layunin nito ay simpleng magpadala ng data sa isang address. At nagbibigay ito ng pangunahing kawalan ng protocol, mababang pagiging maaasahan, dahil maaari itong mawala lamang ang mga piraso ng data. Bukod pa rito, dapat maging handa ang tatanggap sa katotohanang maaaring dumating ang data nang hindi maayos. Iyon ay sinabi, ang protocol ay mayroon ding isang kalamangan, isang mas mataas na rate ng paglipat, dahil sa katotohanan na ang protocol ay limitado sa pagpapadala ng data.

Mayroon ding mga pagkakaiba sa kung paano ipinadala ang data mismo. Sa TCP, ang data ay nai-stream, na nangangahulugan na ang data ay walang mga hangganan. Sa UDP, ipinapadala ang data bilang mga datagram at may mga hangganan, at sinusuri ng tatanggap ang integridad ng data, ngunit kung matagumpay na natanggap ang mensahe.

Ibuod natin:

Ang TCP ay isang maaasahan at tumpak na protocol na pumipigil sa pagkawala ng data. Ang isang mensahe ay palaging ihahatid nang may pinakamataas na katumpakan, o hindi maihahatid sa lahat. Ang tatanggap ay hindi nangangailangan ng lohika para sa pag-order ng data, dahil ang papasok na data ay iuutos na. Ang UDP ay hindi kasing maaasahan, ngunit ito ay isang mas mabilis na data transfer protocol. Ang pagpapadala at pagtanggap ng mga partido ay nangangailangan ng ilang karagdagang lohika upang gumana sa protocol na ito. Ngunit tingnan natin kung paano ito gumagana gamit ang halimbawa ng laro sa computer o larong mobile na nilalaro sa network. Maaaring wala na kaming pakialam kung ano ang dapat dumating 5 segundo ang nakalipas, at maaari naming laktawan ang ilang packet kung hindi dumating ang mga ito sa oras — maaaring mahuli ang laro, ngunit maaari ka pa ring maglaro!

Sa Java, upang gumana sa mga datagram na ipinadala sa UDP, gumagamit kami ng mga bagay ng mga klase ng DatagramSocket at DatagramPacket .

Upang makipagpalitan ng data, ang nagpadala at tagatanggap ay gumagawa ng mga socket ng datagram, ibig sabihin, ang mga pagkakataon ng klase ng DatagramSocket . Ang klase ay may ilang mga constructor. Ang pagkakaiba sa pagitan ng mga ito ay kung saan ang nilikha na socket ay kumonekta:

DatagramSocket () Kumokonekta sa anumang magagamit na port sa lokal na makina
DatagramSocket (int port) Kumokonekta sa tinukoy na port sa lokal na makina
DatagramSocket(int port, InetAddress addr) Kumokonekta sa tinukoy na port sa isang address sa lokal na makina (addr)

Ang klase ay naglalaman ng maraming mga pamamaraan para sa pag-access at pamamahala ng mga parameter ng socket (titingnan natin ang mga ito sa ibang pagkakataon), pati na rin ang mga pamamaraan para sa pagtanggap at pagpapadala ng mga datagram:

ipadala (DatagramPacket pack) Nagpapadala ng mga datagram na naka-pack sa mga packet
tumanggap (DatagramPacket pack) Tumatanggap ng mga datagram na nakaimpake sa mga packet

Ang DatagramPacket ay isang klase na kumakatawan sa isang pakete ng datagram. Ang mga datagram packet ay ginagamit upang ipatupad ang isang walang koneksyon na serbisyo sa paghahatid ng packet. Ang bawat mensahe ay dinadala mula sa isang makina patungo sa isa pa batay lamang sa impormasyong nakapaloob sa packet na iyon. Maramihang mga packet na ipinadala mula sa isang makina patungo sa isa pa ay maaaring iba-iba ang ruta at maaaring dumating sa anumang pagkakasunud-sunod. Ang paghahatid ng mga packet ay hindi ginagarantiyahan.

Mga Konstruktor:

DatagramPacket(byte[] buf, int haba) Lumilikha ng DatagramPacket upang tumanggap ng mga packet na may haba .
DatagramPacket(byte[] buf, int length, InetAddress address, int port) Lumilikha ng packet ng datagram upang magpadala ng mga packet na may haba na haba sa tinukoy na numero ng port sa tinukoy na host.
DatagramPacket(byte[] buf, int offset, int haba) Lumilikha ng DatagramPacket upang tumanggap ng mga packet na may haba na haba , na tumutukoy ng offset sa buffer.
DatagramPacket(byte[] buf, int offset, int haba, InetAddress address, int port) Lumilikha ng packet ng datagram upang magpadala ng mga packet na may haba na haba na may offset na offset sa tinukoy na numero ng port sa tinukoy na host.
DatagramPacket(byte[] buf, int offset, int haba, SocketAddress address) Lumilikha ng packet ng datagram upang magpadala ng mga packet na may haba na haba na may offset na offset sa tinukoy na numero ng port sa tinukoy na host.
DatagramPacket(byte[] buf, int length, SocketAddress address) Lumilikha ng packet ng datagram upang magpadala ng mga packet na may haba na haba sa tinukoy na numero ng port sa tinukoy na host.

Naaalala namin na ang diskarte sa UDP ay hindi nagtatatag ng isang koneksyon. Ang mga packet ay ipinadala sa pag-asang inaasahan sila ng tatanggap. Ngunit maaari kang magtatag ng isang koneksyon gamit ang kumonekta (InetAddress addr, int port) na paraan ng klase ng DatagramSocket .

Ang isang one-way na koneksyon ay itinatag sa host batay sa isang address at port: alinman upang magpadala o tumanggap ng mga datagram. Maaaring wakasan ang koneksyon gamit ang disconnect() na paraan.

Subukan nating magsulat ng server code batay sa DatagramSocket upang makatanggap ng data:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

class Recipient {

   public static void main(String[] args) {
       try {
           DatagramSocket ds = new DatagramSocket(1050);

           while (true) {
               DatagramPacket pack = new DatagramPacket(new byte[5], 5);
               ds.receive(pack);
               System.out.println(new String(pack.getData()));
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}

Gumagawa kami ng object na DatagramSocket para makinig sa port 1050. Kapag nakatanggap ito ng mensahe, ipi-print ito sa console. Ipapadala namin ang salitang "Hello", kaya nililimitahan namin ang laki ng buffer sa limang byte.

Ngayon gagawa kami ng klase ng nagpadala:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

class Sender {
   private String host;
   private int port;

   Sender(String host, int port) {
       this.host = host;
       this.port = port;
   }

   private void sendMessage(String mes) {
       try {
           byte[] data = mes.getBytes();
           InetAddress address = InetAddress.getByName(host);
           DatagramPacket pack = new DatagramPacket(data, data.length, address, port);
           DatagramSocket ds = new DatagramSocket();
           ds.send(pack);
           ds.close();
       } catch (IOException e) {
           System.err.println(e);
       }
   }

   public static void main(String[] args) {
   Sender sender = new Sender("localhost", 1050);
   String message = "Hello";

   Timer timer = new Timer();
   timer.scheduleAtFixedRate(new TimerTask() {
       @Override
       public void run() {
           sender.sendMessage(message);
       }
   }, 1000, 1000);
}

}

Sa paraan ng sendMessage , gumagawa kami ng DatagramPacket at DatagramSocket , at ipinapadala ang aming mensahe. Tandaan na ang close() na paraan ay ginagamit upang isara ang DatagramSocket pagkatapos maipadala ang mensahe.

Bawat segundo ay ipinapakita ng console ng tatanggap ang papasok na mensaheng "Hello" na ipinadala ng nagpadala. Nangangahulugan ito na ang aming komunikasyon ay gumagana nang tama.