Java Dersleri 18 – Network Programlama – UDP

Bu makalede Java’nın network programlama kabiliyetlerinden bahsedeceğim. UDP protokolü uygulamalar arasında datagram adı verilen paketler aracılığıyla haberleşme sağlar. Bu protokol gönderilen paketlerin karşı tarafa gönderilip gönderilmemesi konusunda garanti vermediği gibi paketlerin gönderim sırasında alınmasını da garanti etmez. Herhangi bir datagram paketi gönderebilmek için bir adrese ve port numarasına ihtiyaç duyarsınız. Adres bilgisi paketin ağ üzerinde hangi bilgisayara gönderileceğini belirlerken port bilgisi ise o paketin hangi uygulama için gönderildiğini saptar. Ağ üzerinden haberleşme kabiliyetine sahip uygulamalar genellikle istemci-sunucu yapısına sahiptir. Veri akışı istemcinin sunucuya herhangi bir istek göndermesiyle başlar. Sunucu ise sürekli kendine gelen isteklere cevap verir. Dolayısıyla bu tarz uygulamalar geliştirilirken istemci ve sunucu tarafı koordineli bir şekilde geliştirilir.

Öncelikle sunucu tarafına bir göz atalım. Sunucu tarafında yapmamız gereken iş belirli bir portu dinlemek ve gelen istekleri anlamlandırıp cevap yollamak. Ağ üzerinden herhangi bir portu dinlemek veya o porta datagram paketi yazmak için kullandığımız Java sınıfı DatagramSocket sınıfıdır. Örneğin 6161 portundan paket almak isteyen bir sunucu sınıfmız :

DatagramSocket socket = new DatagramSocket(6161);
byte[] buffer = new byte[24];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);

satırlarını kullanabilir. Burada dikkatimizi çekmesi gereken nokta receive metodunun blocking olması. Yani programımız receive metoduna geldiğinde soketten herhangi bir paket okuyana kadar beklemesi. Dikkatli olunmazsa programımızın takılmasına sebep olabilir. Bu problemi çözmek için bu işlemlerin ayrı bir thread içinde gerçekleştirilmesi gerekir. Ayrıca sunucu yazılımımız soketten tek bir paket değil sürekli veri alması gerekir onun için de bir loop içinde veri okuması gerekir.

 public void run() {
        while (isRunning()) {
                byte[] buffer = new byte[24];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket_.receive(packet);
        }
}

Görüleceği üzere veri byte array olarak okunmaktadır. Veriyi anlamlandırmak yani uygulama protokolünü geliştirmek uygulamanın görevidir. Peki bu paketin hangi bilgisayardan geldiğini nasıl anlayacağız? Bunun cevabı da gayet basit :

InetAddress address = packet.getAddress();
int port = packet.getPort();

DatagramPacket sınıfının getAddress ve getPort metodlarını kullanarak paketin hangi bilgisayardan gönderildiğini
anlayabiliriz. Bu bilgileri yanıt mesajını gönderirken kullanmak üzere saklamanız gereklidir. Paketimizi networkten alıp gönderenin adresini de kaydettikten sonra paketimizdeki veriyi okumayı öğrenelim. Daha önce de belirttiğim üzere DatagramPacket içinde veri byte array olarak saklanır. Onun için byte array’den temel tipleri (int, bool, String) okumayı öğrenmek gerekir. Burada dikkat etmemiz gereken şey sunucu ve istemci tarafında aynı yazma ve okuma mekanizmasını kullanmak gerektiğidir. Temel tipleri okumak ve yazmak için DataInputStream ve DataOutputStream sınıflarından faydalanabiliriz. Tabi işlem yaptığımız nesne byte array olduğu için bu sınıfları ByteArrayInputStream ve ByteArrayOutputStream sınıflarını sarmalayacak şekilde kullanmalıyız. Örneğin byte arrayden temel veri tiplerini okumak için şu kod satırlarından yararlanılabilir :

ByteArrayInputStream bis = new ByteArrayInputStream(packet.getData());
DataInputStream dis = new DataInputStream(bis);
int index = dis.readInt();

Burada packet.getData() ile paketimizde bulunan byte array veri alınmıştır. Oluşturulan ByteArrayInputStream DataInputStream ile sarmalanarak byte array’den temel veri tiplerini kolayca okuyacak bir nesne elde edilmiştir.
Aynı senaryonun yazma kısmına bakacak olursak :

ByteArrayOutputStream baous2 = new ByteArrayOutputStream();
DataOutputStream os = new DataOutputStream(baous2);
os.writeInt(j);
os.flush();
byte[] chunk = baous2.toByteArray();

Buradan hareketle yukarıda hazırladığımız veriyi istemciden sunucuya nasıl gönderileceğini göstererek dersimizi sonlandıralım :

 InetAddress address = InetAddress.getByName("localhost");
 DatagramPacket packet = new DatagramPacket(chunk, chunk.length, address, 6161);
 socket_.send(packet);

Buradaki kod satırlarında yukarıda elde ettiğimiz byte arrayinden bir DatagramPacket nesnesi oluşturup yine DatagramSocket nesnemiz ile localhost 6161 numaralı porta yolluyoruz.

İlgili Yazılar:

  1. Swing Programlama: JTable Temel Kullanım Bu yazımızda en basit haliyle Java UI programlamada sıkça kullandığımız...
  2. Swing Programlama: JTable Hücre Editörleri Bu yazıda kısaca JTable hücreleri için öntanımlı olan editörün dışında...
  3. Swing Programlama : JFileChooser Bu derste Java swing arayüzlerimizden sistemimizdeki dosya sistemine erişimi sağlayan...
  4. Java Dersleri 15 – Koleksiyon API (Collection API) Map Map arayüzü anahtar-değer ikililerini bir arada tutmak için tasarlanmıştır. Matemetikteki...
  5. Java Dersleri 3 – Kontrol Yapıları Bu dersimizde Java’nın kodun akışına yön veren kontrol ifadelerinin...

Fikrin geldiyse buraya yaz


[ Ctrl + Enter ]