Ağdan bahsettiğimizde, OSI modelinden bahsetmeden geçemeyiz.

Bu model açısından, bugün en çok taşıma katmanıyla ilgileniyoruz (4).

Bu, "A noktasından B noktasına" hareket eden verilerle çalıştığımız düzeydir. Taşıma katmanının ana görevi, bir mesajın doğru sırayı koruyarak hedefe iletilmesini sağlamaktır. En yaygın iki taşıma katmanı protokolü şunlardır: TCP ve UDP. Kavramsal olarak farklı şekillerde çalışırlar, ancak her birinin belirli sorunları çözmelerine izin veren kendi avantajları vardır.

İlk olarak, TCP'nin nasıl çalıştığına bakalım.

TCP (İletim Kontrol Protokolü), veri alışverişinden önce ana bilgisayarlar arasında bir bağlantı kurulmasını sağlayan bir ağ protokolüdür.

Bu çok güvenilir bir protokoldür, çünkü başka bir veri paketini her gönderdiğinde bir önceki paketin alınıp alınmadığını kontrol etmesi gerekir.

İletilen paketler sıralanır ve belirli bir pakette sorun varsa (yani alıcı taraf paketin geldiğini onaylamazsa) paket tekrar gönderilir. Sonuç olarak, aktarım hızı nispeten düşüktür, çünkü sıkı izleme ve doğru sıralamayı sağlamak için daha fazla zaman gerekir.

UDP protokolünün "kardeşi" burada devreye giriyor. TCP'den farklı olarak UDP, her paketin sırasını ve durumunu gerçekten önemsemiyor. Sadece teslimat onayı olmadan veri gönderir. Üstelik hiçbir şekilde bağlantı kurmaz ve bağlantı durumuna bağlı değildir.

Amacı basitçe bir adrese veri göndermektir. Ve bu, protokolün ana dezavantajına, düşük güvenilirliğe yol açar, çünkü veri parçalarını kolayca kaybedebilir. Ek olarak, alıcı, verilerin düzensiz olarak gelebileceği gerçeğine hazırlıklı olmalıdır. Bununla birlikte, protokolün veri göndermekle sınırlı olması nedeniyle protokolün daha yüksek bir aktarım hızı gibi bir avantajı da vardır.

Verilerin kendisinin nasıl iletildiği konusunda da farklılıklar vardır. TCP'de veriler akış halindedir, yani verilerin sınırları yoktur. UDP'de, veriler datagramlar olarak iletilir ve sınırları vardır ve alıcı, verilerin bütünlüğünü kontrol eder, ancak yalnızca mesaj başarılı bir şekilde alınırsa.

Özetleyelim:

TCP, veri kaybını önleyen güvenilir ve doğru bir protokoldür. Bir mesaj her zaman maksimum doğrulukla iletilir veya hiç iletilmez. Gelen veri zaten sıralanacağı için alıcının veri sıralaması için mantığa ihtiyacı yoktur. UDP güvenilir değildir, ancak daha hızlı bir veri aktarım protokolüdür. Gönderen ve alan taraflar, bu protokolle çalışmak için bazı ek mantığa ihtiyaç duyarlar. Ancak ağ üzerinden oynanan bir bilgisayar oyunu veya mobil oyun örneğini kullanarak nasıl çalıştığına bir göz atalım. Neyin 5 saniye önce gelmesi gerektiği artık umurumuzda olmayabilir ve zamanında gelmezlerse birkaç paketi atlayabiliriz - oyun gecikebilir, ancak yine de oynayabilirsiniz!

Java'da, UDP üzerinden iletilen datagramlarla çalışmak için DatagramSocket ve DatagramPacket sınıflarının nesnelerini kullanırız .

Veri alışverişi için, gönderici ve alıcı datagram yuvaları, yani DatagramSocket sınıfının örnekleri oluşturur. Sınıfın birkaç kurucusu vardır. Aralarındaki fark, oluşturulan soketin bağlanacağı yerdir:

DatagramSocket () Yerel makinedeki herhangi bir kullanılabilir bağlantı noktasına bağlanır
DatagramSocket (int bağlantı noktası) Yerel makinede belirtilen bağlantı noktasına bağlanır
DatagramSocket(int bağlantı noktası, InetAddress adresi) Yerel makinedeki bir adreste (addr) belirtilen bağlantı noktasına bağlanır

Sınıf, soket parametrelerine erişmek ve bunları yönetmek için birçok yöntem (bunlara biraz sonra bakacağız) ve datagramları almak ve göndermek için yöntemler içerir:

gönder(DatagramPacket paketi) Paketler halinde paketlenmiş datagramları gönderir
alma (DatagramPacket paketi) Paketler halinde paketlenmiş datagramları alır

DatagramPacket , bir datagram paketini temsil eden bir sınıftır. Datagram paketleri, bağlantısız bir paket dağıtım hizmetini uygulamak için kullanılır. Her mesaj, yalnızca o pakette bulunan bilgilere dayalı olarak bir makineden diğerine yönlendirilir. Bir makineden diğerine gönderilen çoklu paketler farklı şekilde yönlendirilebilir ve herhangi bir sırada gelebilir. Paketlerin teslimi garanti edilmez.

İnşaatçılar:

DatagramPacket(byte[] buf, int uzunluk) Uzunluktaki paketleri kabul etmek için bir DatagramPacket oluşturur .
DatagramPacket(byte[] buf, int uzunluk, InetAddress adresi, int bağlantı noktası) Uzunluktaki paketleri belirtilen ana bilgisayardaki belirtilen bağlantı noktası numarasına göndermek için bir datagram paketi oluşturur .
DatagramPacket(bayt[] buf, int ofset, int uzunluk) Arabellekte bir uzaklık belirterek, uzunluktaki paketleri kabul etmek için bir DatagramPacket oluşturur .
DatagramPacket(bayt[] buf, int ofset, int uzunluk, InetAddress adresi, int bağlantı noktası) Belirtilen ana bilgisayarda belirtilen bağlantı noktası numarasına ofset ofseti ile uzunluk uzunluğundaki paketleri göndermek için bir datagram paketi oluşturur .
DatagramPacket(bayt[] buf, int ofset, int uzunluk, SocketAddress adresi) Belirtilen ana bilgisayarda belirtilen bağlantı noktası numarasına ofset ofseti ile uzunluk uzunluğundaki paketleri göndermek için bir datagram paketi oluşturur .
DatagramPacket(byte[] buf, int uzunluk, SocketAddress adresi) Uzunluktaki paketleri belirtilen ana bilgisayardaki belirtilen bağlantı noktası numarasına göndermek için bir datagram paketi oluşturur .

UDP yaklaşımının bir bağlantı kurmadığını hatırlıyoruz. Paketler, alıcının onları beklediği umuduyla gönderilir. Ancak DatagramSocket sınıfının connect(InetAddress addr, int port) yöntemini kullanarak bağlantı kurabilirsiniz .

Bir adres ve bağlantı noktasına dayalı olarak ana bilgisayarla tek yönlü bir bağlantı kurulur: datagramları göndermek veya almak için. Bağlantı, bağlantı kesme() yöntemi kullanılarak sonlandırılabilir .

Veri almak için DatagramSocket tabanlı sunucu kodu yazmaya çalışalım :

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

Port 1050'de dinlemek için bir DatagramSocket nesnesi oluşturuyoruz. Bir mesaj aldığında bunu konsola yazdırıyor. "Merhaba" kelimesini ileteceğiz, bu nedenle arabellek boyutunu beş baytla sınırlıyoruz.

Şimdi gönderen sınıfını oluşturacağız:

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

}

sendMessage metodunda DatagramPacket ve DatagramSocket oluşturup mesajımızı gönderiyoruz. İleti gönderildikten sonra DatagramSocket'ı kapatmak için close() yönteminin kullanıldığını unutmayın .

Alıcının konsolu, gönderici tarafından gönderilen gelen "Merhaba" mesajını her saniye görüntüler. Bu, iletişimimizin tamamen doğru çalıştığı anlamına gelir.