1 Prof. Dr. Th. Letschert Çeviri: Turgay Akbaş FB MNI 14. Mai 2013 Alıştırmalar 5 - Dağıtık Sistemler Alıştırma 1 Ağ/Soket programlamayı kullanarak bir aktif Buffer gerçekleştiriniz. Buffer sunucu, producer ve consumer’lar ise istemcilerdir. Producer ve Consumer’lar aktif Buffer ile UDP üzerinden iletişim kurmalıdırlar. İp ucu Aktif Buffer mesajları göndericileriyle birlikte göndermelidir. En iyi yöntem bu yardımcı sınıfın UDP-iletişimi için geliştirilmesidir. Örnek olarak: package aufgabe_1; import import import import import import import import import import import java.io.ByteArrayInputStream; java.io.ByteArrayOutputStream; java.io.IOException; java.io.ObjectInputStream; java.io.ObjectOutputStream; java.io.Serializable; java.net.DatagramPacket; java.net.DatagramSocket; java.net.InetAddress; java.net.SocketException; java.net.UnknownHostException; public class UDPLayer { public static class Pkt { Pkt(InetAddress senderAdr, int senderPort, Serializable msg) { this.senderAdr = senderAdr; this.senderPort = senderPort; this.msg = msg; } InetAddress senderAdr; int senderPort; Serializable msg; } private private private private InetAddress remoteAdr; int remotePort; int localPort; DatagramSocket dtgrmSocket; public UDPLayer (String localPort) throws SocketException { this.localPort = Integer.valueOf(localPort).intValue(); dtgrmSocket = new DatagramSocket(this.localPort); } public UDPLayer () throws SocketException { this.localPort = 0; dtgrmSocket = new DatagramSocket(); } 2 public void setDestination (String host, String port) throws SocketException, UnknownHostException { this.remotePort = Integer.valueOf(port).intValue(); remoteAdr = InetAddress.getByName(host); } public void send(Serializable msg) { send(msg, this.remoteAdr, this.remotePort); } public void send(Serializable msg, InetAddress remoteAdr, int remotePort) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos; try { oos = new ObjectOutputStream(baos); oos.writeObject(msg); oos.flush(); byte buf[] = baos.toByteArray(); DatagramPacket pkt = new DatagramPacket(buf, buf.length, remoteAdr, remotePort); dtgrmSocket.send(pkt); oos.close(); } catch (IOException e) { e.printStackTrace(); } } public Serializable receive() throws IOException, ClassNotFoundException { byte[] bufRcv = new byte[256]; DatagramPacket pktRcv = new DatagramPacket(bufRcv, bufRcv.length); dtgrmSocket.receive(pktRcv); ByteArrayInputStream bais = new ByteArrayInputStream(bufRcv); ObjectInputStream ois = new ObjectInputStream(bais); Serializable msg = (Serializable) ois.readObject(); bais.close(); ois.close(); return msg; } public Pkt receivePkt() throws IOException, ClassNotFoundException { byte[] bufRcv = new byte[256]; DatagramPacket rcvpkt = new DatagramPacket(bufRcv, bufRcv.length); dtgrmSocket.receive(rcvpkt); ByteArrayInputStream bais = new ByteArrayInputStream(bufRcv); ObjectInputStream ois = new ObjectInputStream(bais); Serializable msg = (Serializable) ois.readObject(); bais.close(); ois.close(); return new Pkt(rcvpkt.getAddress(), rcvpkt.getPort(), msg); } } 3 Alıştırma 2 RMI–uygulaması olarak bir aktif Buffer gerçekleştiriniz. Buffer sunucu, producer ve consumer’lar ise istemcilerdir. Producer ve consumer’lar Buffer ile ayrılmış metot çağırımları put ve put üzerinden haberleşmelidirler. Dağıtıklık şeffaf olduğu için çözüm somut olarak daha kolaydır. Prensipte, doğal olarak, Alıştırma 1’de ki sınıf çalıştırılmalıdır. RMI’nin dağıtıklığı nasıl sağlayacağını açıklayınız. Uzak çağrının bloklayabileceğine dikkat ediniz. İletişim nasıl yürür? Sunucu tarafında hangi süreç ve thread’ler aktif olmalıdır? Alıştırma 3 Aktif bir Buffer’ı bu şekilde gerçekleştirmek mümkünmüdür: Sunucu pasif bir buffer’dan oluşur ve uygun bir mesaj gelmesi durumunda mesajı işleyebilmek için bir iç buffer kullanılır. Aşağıda gösterildiği gibi: package aufgabe_3; import import import import java.io.IOException; java.io.Serializable; java.net.InetAddress; java.net.SocketException; import aufgabe_3.UDPLayer.Pkt; public class Buffer_Server<T extends Serializable> implements Runnable { private static class Buffer_Passive <T extends Serializable> { private T place; private boolean empty = true; public synchronized void put(T t) { while (! empty) try { wait(); } catch (InterruptedException e) { // ignore } place = t; empty = false; notify(); } public synchronized T get() { while ( empty ) try { wait(); } catch (InterruptedException e) { // ignore } empty = true; notify(); return place; } } private UDPLayer udpLayer; private Buffer_Passive<T> buffer = new Buffer_Passive<>(); public Buffer_Server(String port) throws SocketException { udpLayer = new UDPLayer(port); 4 } @Override public void run() { while (true) { pkt = udpLayer.receivePkt(); // Nachricht mit Hilfe von buffer verarbeiten // und dann die Antwort senden. } } public static void main(String[] args) throws SocketException { String port; if (args.length == 1) { port = args[0]; } else { port = "4711"; } Buffer_Server<Integer> bufferServer = new Buffer_Server<>(port); new Thread(bufferServer).start(); } } Alıştırma 4 1. “Middleware”’ den ne anlıyorsunuz? 2. Web teknolojileri bir “Middleware” midir? 3. Bir pasif monitörün wait ve notify talimatları bir aktif monitörde nasıl uygulanır? 4. Pasif bir monitörün aktif bir monitörde nasıl uygulanacağını açıklayınız.Eğer pasif bir monitör aktif bir monitörde bir bileşen olarak kullanılacaksa prosedür nedir? 5. Dağıtıklığın formel modelinde(asenkron veya senkron) lokal threadlerin başlangıçlarının bir süreç içinde modellenmesi mümkünmüdür? Alıştırma 5 Size göre hangi kütüphane bileşenleri/dil ortamları aktif monitörlerin gerçekleştirimi için faydalıdır ?