Basit bir soket hesap makinesi

Dağıtık sistemler dersinde ilk ödev olarak basit bir hesap makinesi yapmamız istendi. Özelliği soketler üzerinden haberleşen sunucu ve istemciye sahip olmasıydı. Bu işin yapılmasında en çok karşılaşılan bir problemle arkadaşım Cumhur da karşılaşınca acaba o problemi nasıl çözüyorduk, threadlerle nasıl yapıyorduk sorularına cevaplar bulmak için projeyi genişletmeye karar verdim.

Proje çok basit 4 işlem yapıyor. Sadece iki sayı alıyor. İki farklı uygulama (JFrame) içeriyor. Biri CalcServerFrame.java adındaki sunucumuz, diğeri de CalcClientFrame.java adındaki istemcimiz. İstemci kolay anlaşılır bir yapıda. Kullanıcı hesapla düğmesine bastığı zaman kullanıcının verdiği sunucu adresine verilen porttan bağlanıp Islem sınıfı gönderiyor. Karmaşıklık sunucu tarafında. Sunucuda iki düğme var. Çalıştır düğmesi sunucu threadini yaratarak threadi başlatıyor. Buradaki ince nokta threadin çalışmaya devam ederken bizim arayüzde herhangi bir problem olmaması. Bunu Thread'ten ürettiğimiz ServerThread sınıfı içerisine run metodunu gerçekleştirip, threadi çalıştırmak için start() metodunu çağırarak yapıyoruz.
Bağlan düğmesini eylemi gerçekleştiren kısmı:
btnBaglan.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
// Sunucu olarak calisacak olan is parcacigini
// yaratip baslatalim
st = new ServerThread();
// FIX start dedigimiz zaman swingteki dugmenin
// takilma problemi olmuyor
st.start();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Bir hata oluştu:"
+ ex.getMessage());
}
}
ServerThread sınıfımız:
class ServerThread extends Thread {

private ServerSocket ss;

private boolean acik = true;

/**
* Baslat dugmesine basilinca calisacak olan baslangic metodu
*/
public void run() {
try {
System.out.println("Sunucu başlatılıyor!");
// Sunucunun dinleme yapacagi soketi yaratiyoruz
ss = new ServerSocket(Integer.parseInt(txtPort.getText()));
// Bu sunucu surekli olarak calisacak
acik = true;

while (acik) {
try {
// Istemciden talep gelmesini bekliyoruz
Socket socket = ss.accept();
// Istemci talebi geldigi zaman istemciden Islem
// nesnesini okuyoruz
ObjectInputStream in = new ObjectInputStream(socket
.getInputStream());
// Ve bu islem nesnesi uzerinde islemi
// gerceklestiriyoruz
Islem islem = isle((Islem) in.readObject());
// Ekranan bize bir istemci talebi geldigini adresiyle
// yaziyoruz
System.out.println("Bağlantı geldi:"
+ socket.getInetAddress().getHostName());
// Daha sonra islem sonucunu aktarmak icin islem
// nesnesini
ObjectOutputStream out = new ObjectOutputStream(socket
.getOutputStream());
// istemciye geri donduruyoruz
out.writeObject(islem);
} catch (Exception e) {
// Hata olusmasi durumunda ekrana yaziyoruz
System.out.println(e.getMessage());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

public void stopServer() {
try {
// Sunucunun dinleme yaptigi soketi kapatalim
ss.close();
// dinleme dongusunden cikmamiz gerekli
acik = false;
// thread durdurulsun
this.interrupt();
System.out.println("Sunucu kapatıldı!");
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Bu metodun amaci aldigi Islem nesnesinin talep ettigi matematiksel
* islemi gerceklestirip sonucu Islem nesnesine yazarak Islem nesnesini
* geri dondurmektedir.
*
* @param islem
* @return
*/
private Islem isle(Islem islem) {
// Islem toplama
if (islem.getIslem().equals(Islem.TOPLA)) {
islem.setSonuc(islem.getSayi1() + islem.getSayi2());
}
// Islem carpma
if (islem.getIslem().equals(Islem.CARP)) {
islem.setSonuc(islem.getSayi1() * islem.getSayi2());
}
// Islem cikarma
if (islem.getIslem().equals(Islem.CIKAR)) {
islem.setSonuc(islem.getSayi1() - islem.getSayi2());
}
// Islem bolme
if (islem.getIslem().equals(Islem.BOL)) {
islem.setSonuc((float) islem.getSayi1()
/ (float) islem.getSayi2());
}
return islem;
}
}

Daha ayrıntılı olarak kodu incelemek ve nasıl çalıştığını görmek için şu eclipse projesini indirebilirsiniz. Sunucuyu (CalcServerFrame.java) önce çalıştırmanız gerekiyor. Daha sonra herhangi bir makineden sunucuya istemciden (CalcClientFrame.java) bağlanabilirsiniz.

Hiç yorum yok: