
Merhaba,
Bugün Java ile GUI Tabanlı bir Soket Haberleşme Programı kodlayacağız.
Konuya Geçelim;
Kütüphanelerimiz:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

Öncelikli olarak; Sabitler ve değişkenleri tanımlayalım;
Java:
public class Main {
private static final int VARSAYILAN_PORT = 12345;
private static final String VARSAYILAN_SUNUCU = "localhost";
private static final String ANAHTAR = "AesKey";
private JFrame pencere;
private JTextArea sohbetAlani;
private JTextField mesajGirisi;
private JList<String> kullaniciListesi;
private DefaultListModel<String> kullaniciListesiModeli;
private Socket istemciSoketi;
private PrintWriter mesajGonderici;
private BufferedReader mesajOkuyucu;
private String kullaniciAdi;
private ServerSocket sunucuSoketi;
private HashMap<String, PrintWriter> istemciler;
private HashSet<String> cevrimiciKullanicilar;
private boolean sunucuMu;
Türkçe olduğu için kod anlaşılır zaten fakat yine de açıklamak gerekirse.
Portu ve sunucu yani girilecek IP adresini burada tutuyoruz.
Sonrasında değişecek, "AesKey" giden gelen veriler şifrelenecek bu yüzden. Bu kısım değişebilir.
Sonrasında, GUI için bileşenleri tanımlıyoruz.

Şimdi
Constructor
yani Kurucu Method'u tanımlıyoruz;
Java:
public Main() {
pencere = new JFrame("Main");
pencere.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pencere.setSize(600, 400);
pencere.setLayout(new BorderLayout());
sohbetAlani = new JTextArea();
sohbetAlani.setEditable(false);
pencere.add(new JScrollPane(sohbetAlani), BorderLayout.CENTER);
kullaniciListesiModeli = new DefaultListModel<>();
kullaniciListesi = new JList<>(kullaniciListesiModeli);
pencere.add(new JScrollPane(kullaniciListesi), BorderLayout.EAST);
JPanel altPanel = new JPanel(new BorderLayout());
mesajGirisi = new JTextField();
altPanel.add(mesajGirisi, BorderLayout.CENTER);
JButton gonderButonu = new JButton("Gönder");
altPanel.add(gonderButonu, BorderLayout.EAST);
pencere.add(altPanel, BorderLayout.SOUTH);
gonderButonu.addActionListener(e -> mesajGonder());
mesajGirisi.addActionListener(e -> mesajGonder());
kullaniciListesi.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && !sunucuMu) {
String secilenKullanici = kullaniciListesi.getSelectedValue();
if (secilenKullanici != null && !secilenKullanici.equals(kullaniciAdi)) {
String ozelMesaj = JOptionPane.showInputDialog(pencere, secilenKullanici + " için özel mesaj:");
if (ozelMesaj != null && !ozelMesaj.trim().isEmpty()) {
mesajGonderici.println(sifrele("OZEL:" + secilenKullanici + ":" + ozelMesaj));
}
}
}
}
});
JFrame
oluşturup başlığı "Main" olarak ayarladık.Kapatıldığında programın sona ermesi için
EXIT_ON_CLOSE
kullanıyoruz."BorderLayout" vs. pencere boyutlarını ayarlamak için kullanıyoruz.

gonderButonu ve mesajGirisi’ne ActionListener ekliyoruz; her ikisi de
mesajGonder()
metodunu çağırıyoruz.Sunucu modunda (sunucuMu) bu özellik devre dışı bırakıyoruz. Bu kısım öncemli.
Java:
private void mesajGonder() {
String mesaj = mesajGirisi.getText().trim();
if (mesaj.isEmpty()) {
// boş mesaj atılmaması için
return;
}
if (sunucuMu) {
// sunucu modunda tüm mesajı
// istemcilere yaymak için kullandık
String formatliMesaj = "MESAJ:" + kullaniciAdi + ":" + mesaj;
yayinYap(sifrele(formatliMesaj));
sohbetAlani.append(kullaniciAdi + ": " + mesaj + "\n");
} else {
// burdada istemci modunda sunucuya mesaj
if (mesajGonderici != null) {
mesajGonderici.println(sifrele(mesaj));
} else {
hataGoster("Bağlantı kurulmadı!");
}
}
mesajGirisi.setText("");
}
Mesaj giriş alanındaki metinde boşluk olursa,
trim()
ile siliyoruz.Boş mesaj gönderilmemesi için
return
ile ile iptal ediyoruz.Mesaj, MESAJ:kullaniciAdi:mesaj formatında hazırlanıyor.
yayinYap()
ile tüm istemcilere şifrelenerek gönderilir.Sunucunun kendi mesajı sohbetAlani’nda gösteriliyor.

Şimdi uygulamayı başlatma kısmını yazalım;
Java:
private void baslat() {
//gui bileşenlerini tanımlıyoruz
JPanel ayarPaneli = new JPanel(new GridLayout(4, 2));
JTextField sunucuAdresiAlani = new JTextField(VARSAYILAN_SUNUCU);
JTextField portAlani = new JTextField(String.valueOf(VARSAYILAN_PORT));
JTextField kullaniciAdiAlani = new JTextField();
// bu kısım önemli
// sunucu modunda başlatırsak bağlantıları biz alacağız
JCheckBox sunucuModuSecimi = new JCheckBox("Sunucu olarak başlat");
ayarPaneli.add(new JLabel("Sunucu IP:"));
ayarPaneli.add(sunucuAdresiAlani);
ayarPaneli.add(new JLabel("Port:"));
ayarPaneli.add(portAlani);
ayarPaneli.add(new JLabel("Kullanıcı Adı:"));
ayarPaneli.add(kullaniciAdiAlani);
ayarPaneli.add(new JLabel("Mod:"));
ayarPaneli.add(sunucuModuSecimi);
int sonuc = JOptionPane.showConfirmDialog(null, ayarPaneli, "Bağlantı Ayarları", JOptionPane.OK_CANCEL_OPTION);
if (sonuc != JOptionPane.OK_OPTION) {
System.exit(0);
}
// sunucuadresi değişkenindeki
// boş alanları temizliyoruz
String sunucuAdresi = sunucuAdresiAlani.getText().trim();
int port;
try {
// port girişini int olarak almamız lazım
port = Integer.parseInt(portAlani.getText().trim());
} catch (NumberFormatException e) {
hataGoster("Geçersiz port numarası!");
System.exit(1);
return;
}
kullaniciAdi = kullaniciAdiAlani.getText().trim();
sunucuMu = sunucuModuSecimi.isSelected();
if (kullaniciAdi.isEmpty()) {
hataGoster("Kullanıcı adı boş olamaz!");
System.exit(1);
return;
}
try {
if (sunucuMu) {
istemciler = new HashMap<>();
cevrimiciKullanicilar = new HashSet<>();
sunucuSoketi = new ServerSocket(port);
sohbetAlani.append("Sunucu başlatıldı, port: " + port + "\n");
pencere.setTitle("Main Sunucusu");
new Thread(this::sunucuyuCalistir).start();
} else {
istemciSoketi = new Socket(sunucuAdresi, port);
mesajGonderici = new PrintWriter(istemciSoketi.getOutputStream(), true);
mesajOkuyucu = new BufferedReader(new InputStreamReader(istemciSoketi.getInputStream()));
pencere.setTitle("Main: " + kullaniciAdi);
new Thread(this::istemciyiCalistir).start();
}
pencere.setVisible(true);
} catch (IOException e) {
hataGoster("Bağlantı hatası: " + e.getMessage());
System.exit(1);
}
}
Socket ile sunucuya bağlanıyoruz.
mesajGonderici
ve mesajOkuyucu
başlatılır.Başlık "Main: kullanıcıAdi" oluyor..
istemciyiCalistir()
ayrı bir iş parçacığında çalıyor.Burda bağlantıyı alıp, GUI ile gösterimini sağlıyoruz.

Şimdi sunucuyu çalıştırma fonksiyonunu yazalım;
Java:
private void sunucuyuCalistir() {
try {
while (true) {
Socket istemci = sunucuSoketi.accept();
new Thread(() -> istemciyiYonet(istemci)).start();
}
} catch (IOException e) {
if (!sunucuSoketi.isClosed()) {
sohbetAlani.append("Sunucu hatası: " + e.getMessage() + "\n");
}
}
}
Sonsuz bir döngüde
sunucuSoketi.accept()
ile yeni istemci bağlantıları bekliyoruz.Bu kısımda for ile sınırı belirleyebilirsiniz. Burda while kullandık.
Her yeni istemci için
istemciyiYonet()
metodunuu ayrı bir iş parçacığında çalıştırıyoruz.Hata durumunda (soket kapanmadıysa), hata mesajı sohbetAlani’na yazıyoruz.
Java:
private void istemciyiYonet(Socket istemci) {
// bu metot sunucunun her istemciyi ayri bir is parcaciginda yonetmesini saglar
// yeni baglanan bir istemci icin cagrilir
// istemcinin mesajlarini alir ve isler
// diger istemcilere mesajlari iletir
String istemciKullaniciAdi = null;
// istemci kullanici adi burada tutulur
// baslangicta null olarak tanimlanir
PrintWriter istemciGonderici = null;
// istemciye mesaj gonderen printwriter
// otomatik flush ile hizli gonderim saglar
BufferedReader istemciOkuyucu = null;
// istemciden mesaj okuyan bufferedreader
// gelen veriyi satir satir okur
try {
// try blogu hatalari yakalamak icin
// istemci iletisimi burada baslar
istemciGonderici = new PrintWriter(istemci.getOutputStream(), true);
// printwriter istemci soketinden olusturulur
// true parametresi otomatik flush icin
istemciOkuyucu = new BufferedReader(new InputStreamReader(istemci.getInputStream()));
// bufferedreader istemci girdisini okur
// inputstreamreader ile baytlar karaktere cevrilir
while (true) {
// sonsuz dongu kullanici adi almak icin
// istemci dogru bir ad verene kadar devam eder
istemciGonderici.println("KULLANICI_ADI_GONDER");
// istemciye kullanici adi gonder komutu yollanir
// bu istemciden ad istemek icin
istemciKullaniciAdi = istemciOkuyucu.readLine();
// istemciden gelen kullanici adi okunur
// satir satir okuma yapar
if (istemciKullaniciAdi == null || istemciKullaniciAdi.trim().isEmpty()) {
// kullanici adi null veya bos ise
// istemci baglantisi kesilir
return;
// metottan cikilir
}
synchronized (istemciler) {
// istemciler uzerinde eszamanli kontrol
// coklu istemci cakismasini onler
if (!istemciler.containsKey(istemciKullaniciAdi)) {
// kullanici adi daha once alinmamissa
istemciler.put(istemciKullaniciAdi, istemciGonderici);
// istemci hashmap e eklenir
cevrimiciKullanicilar.add(istemciKullaniciAdi);
// cevrimici kullanicilara eklenir
break;
// donguden cikilir
} else {
// kullanici adi zaten varsa
istemciGonderici.println("KULLANICI_ADI_ALINMIS");
// istemciye hata mesaji gonderilir
// yeni bir ad istenmesi icin
}
}
}
yayinYap(sifrele("SISTEM:" + istemciKullaniciAdi + " sohbete katıldı."));
// sistem mesaji tum istemcilere yayinlanir
// yeni istemci katildi bilgisi verilir
yayinYap(sifrele("CEVRIMICI_KULLANICILAR:" + String.join(",", cevrimiciKullanicilar)));
// guncel kullanici listesi tum istemcilere gonderilir
// cevrimici kullanicilar virgulle ayrilir
sohbetAlani.append(istemciKullaniciAdi + " bağlandı.\n");
// sunucu gui sinde baglanti bildirimi gosterilir
// sohbet alanina eklenir
String sifreliMesaj;
// gelen sifreli mesajlar icin degisken
while ((sifreliMesaj = istemciOkuyucu.readLine()) != null) {
// istemciden mesajlar okunur
// null olana kadar devam eder
String mesaj = coz(sifreliMesaj);
// sifreli mesaj cozulur
// normal metne donusturulur
sohbetAlani.append(istemciKullaniciAdi + ": " + mesaj + "\n");
// mesaj sunucu gui sinde gosterilir
// kullanici adi ile birlikte eklenir
if (mesaj.startsWith("OZEL:")) {
// mesaj ozel mesaj ise
//split ile bölüyoruz
// belirli bir ayraç kullanabilirsiniz
String[] parcalar = mesaj.split(":", 3);
// mesaj uce bolunur ozel alici mesaj
//size kalmış yine 10'a 5'e farketmez
if (parcalar.length == 3) {
String alici = parcalar[1];
String ozelMesaj = parcalar[2];
synchronized (istemciler) {
PrintWriter aliciGonderici = istemciler.get(alici);
if (aliciGonderici != null) {
aliciGonderici.println(sifrele("OZEL:" + istemciKullaniciAdi + ":" + ozelMesaj));
}
istemciGonderici.println(sifrele("OZEL:" + istemciKullaniciAdi + ":" + ozelMesaj));
}
}
} else {
yayinYap(sifrele("MESAJ:" + istemciKullaniciAdi + ":" + mesaj));
// tum istemcilere mesaj yayinlanir
// mesaj kullanici adi ile formatlanir
}
}
} catch (IOException e) {
// hata durumunda calisir
// genellikle baglanti kopmasi
if (istemciKullaniciAdi != null) {
// kullanici adi varsa
sohbetAlani.append(istemciKullaniciAdi + " bağlantısı koptu: " + e.getMessage() + "\n");
}
} finally {
if (istemciKullaniciAdi != null) {
synchronized (istemciler) {
istemciler.remove(istemciKullaniciAdi);
cevrimiciKullanicilar.remove(istemciKullaniciAdi);
}
yayinYap(sifrele("SISTEM:" + istemciKullaniciAdi + " sohbetten ayrıldı."));
yayinYap(sifrele("CEVRIMICI_KULLANICILAR:" + String.join(",", cevrimiciKullanicilar)));
sohbetAlani.append(istemciKullaniciAdi + " ayrıldı.\n");
}
try {
if (istemciOkuyucu != null) istemciOkuyucu.close();
if (istemciGonderici != null) istemciGonderici.close();
if (istemci != null) istemci.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Şimdi sunucu kısmının tüm Client'lere mesaj gönderelim;
Java:
private void yayinYap(String sifreliMesaj) {
// bu metot tum istemcilere mesaj gonderir
// sifreli mesaj parametre olarak alinir
// sunucunun ana iletisim yontemi
// sistem mesajlari icin kullanilir
// genel mesajlar icin kullanilir
// cevrimici kullanici listesi icin kullanilir
synchronized (istemciler) {
// eszamanli erisim icin kilitlenir
// coklu is parcacigi sorunlarini onler
// istemciler hashmap i korunur
for (PrintWriter gonderici : istemciler.values()) {
// her istemci printwriter i uzerinde dongu
// tum istemcilere ulasilir
gonderici.println(sifreliMesaj);
gonderici.flush();
}
}
}

İstemciyi gönderme fonksiyonu gibi, çalıştırma fonksiyonunu da yazalım;
ANAHTAR’dan
bir AES anahtarı oluşturup, Cipher şifreleme moduna ayarlıyoruz.Mesajı byte'lara çevirip, şifreliyoruz ve Base64 ile kodluyoruz. Hata durumunda orijinal mesaj döner.
Java:
private void istemciyiCalistir() {
try {
String sifreliMesaj;
while ((sifreliMesaj = mesajOkuyucu.readLine()) != null) {
String mesaj = coz(sifreliMesaj);
if (mesaj.equals("KULLANICI_ADI_GONDER")) {
mesajGonderici.println(kullaniciAdi); // Kullanıcı adı şifrelenmez
} else if (mesaj.equals("KULLANICI_ADI_ALINMIS")) {
hataGoster("Bu kullanıcı adı zaten alınmış!");
baglantiyiKes();
return;
} else if (mesaj.startsWith("MESAJ:")) {
String[] parcalar = mesaj.split(":", 3);
if (parcalar.length == 3) {
sohbetAlani.append(parcalar[1] + ": " + parcalar[2] + "\n");
}
} else if (mesaj.startsWith("OZEL:")) {
String[] parcalar = mesaj.split(":", 3);
if (parcalar.length == 3) {
sohbetAlani.append("[Özel] " + parcalar[1] + ": " + parcalar[2] + "\n");
}
} else if (mesaj.startsWith("SISTEM:")) {
sohbetAlani.append("[Sistem] " + mesaj.substring(7) + "\n");
} else if (mesaj.startsWith("CEVRIMICI_KULLANICILAR:")) {
String[] kullanicilar = mesaj.substring(23).split(",");
kullaniciListesiModeli.clear();
for (String kullanici : kullanicilar) {
if (!kullanici.isEmpty()) {
kullaniciListesiModeli.addElement(kullanici);
}
}
}
}
} catch (IOException e) {
hataGoster("Sunucu bağlantısı koptu: " + e.getMessage());
} finally {
baglantiyiKes();
}
}

Şimdi güvenli iletişim için AES şifreleme ve çözme fonksiyonu kuralım;
Java:
private String sifrele(String mesaj) {
try {
SecretKeySpec anahtar = new SecretKeySpec(ANAHTAR.getBytes(), "AES");
Cipher sifreleyici = Cipher.getInstance("AES");
sifreleyici.init(Cipher.ENCRYPT_MODE, anahtar);
byte[] sifreliVeri = sifreleyici.doFinal(mesaj.getBytes());
return Base64.getEncoder().encodeToString(sifreliVeri);
} catch (Exception e) {
e.printStackTrace();
return mesaj; // Hata olursa şifresiz döner
}
}
private String coz(String sifreliMesaj) {
try {
SecretKeySpec anahtar = new SecretKeySpec(ANAHTAR.getBytes(), "AES");
Cipher cozucu = Cipher.getInstance("AES");
cozucu.init(Cipher.DECRYPT_MODE, anahtar);
byte[] sifreliVeri = Base64.getDecoder().decode(sifreliMesaj);
byte[] cozulmusVeri = cozucu.doFinal(sifreliVeri);
return new String(cozulmusVeri);
} catch (Exception e) {
e.printStackTrace();
return sifreliMesaj; // Hata olursa şifreli hali döner
}
}

Şimdi yardımcı methodları tanımlayalım, bağlantı kesme v.s;
Java:
private void hataGoster(String mesaj) {
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(pencere, mesaj, "Hata", JOptionPane.ERROR_MESSAGE));
}
private void baglantiyiKes() {
try {
if (mesajGonderici != null) mesajGonderici.close();
if (mesajOkuyucu != null) mesajOkuyucu.close();
if (istemciSoketi != null) istemciSoketi.close();
if (sunucuSoketi != null) sunucuSoketi.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Uygulamayı başlatma Main methodunu tanımlayarak, bitirelim;
Java:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Main uygulama = new Main();
uygulama.baslat();
});
}

Java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class Main {
private static final int VARSAYILAN_PORT = 12345;
private static final String VARSAYILAN_SUNUCU = "localhost";
private static final String ANAHTAR = "AesKey";
private JFrame pencere;
private JTextArea sohbetAlani;
private JTextField mesajGirisi;
private JList<String> kullaniciListesi;
private DefaultListModel<String> kullaniciListesiModeli;
private Socket istemciSoketi;
private PrintWriter mesajGonderici;
private BufferedReader mesajOkuyucu;
private String kullaniciAdi;
private ServerSocket sunucuSoketi;
private HashMap<String, PrintWriter> istemciler;
private HashSet<String> cevrimiciKullanicilar;
private boolean sunucuMu;
public Main() {
pencere = new JFrame("Socket Haberleşme by Slow");
pencere.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pencere.setSize(600, 400);
pencere.setLayout(new BorderLayout());
sohbetAlani = new JTextArea();
sohbetAlani.setEditable(false);
pencere.add(new JScrollPane(sohbetAlani), BorderLayout.CENTER);
kullaniciListesiModeli = new DefaultListModel<>();
kullaniciListesi = new JList<>(kullaniciListesiModeli);
pencere.add(new JScrollPane(kullaniciListesi), BorderLayout.EAST);
JPanel altPanel = new JPanel(new BorderLayout());
mesajGirisi = new JTextField();
altPanel.add(mesajGirisi, BorderLayout.CENTER);
JButton gonderButonu = new JButton("Gönder");
altPanel.add(gonderButonu, BorderLayout.EAST);
pencere.add(altPanel, BorderLayout.SOUTH);
gonderButonu.addActionListener(e -> mesajGonder());
mesajGirisi.addActionListener(e -> mesajGonder());
kullaniciListesi.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && !sunucuMu) {
String secilenKullanici = kullaniciListesi.getSelectedValue();
if (secilenKullanici != null && !secilenKullanici.equals(kullaniciAdi)) {
String ozelMesaj = JOptionPane.showInputDialog(pencere, secilenKullanici + " için özel mesaj:");
if (ozelMesaj != null && !ozelMesaj.trim().isEmpty()) {
mesajGonderici.println(sifrele("OZEL:" + secilenKullanici + ":" + ozelMesaj));
}
}
}
}
});
pencere.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
baglantiyiKes();
}
});
}
private void mesajGonder() {
String mesaj = mesajGirisi.getText().trim();
if (mesaj.isEmpty()) {
return; // Boş mesaj gönderilmez
}
if (sunucuMu) {
// Sunucu modunda, mesajı tüm istemcilere yayınla
String formatliMesaj = "MESAJ:" + kullaniciAdi + ":" + mesaj;
yayinYap(sifrele(formatliMesaj));
sohbetAlani.append(kullaniciAdi + ": " + mesaj + "\n"); // Sunucunun kendi mesajını göster
} else {
// İstemci modunda, sunucuya mesaj gönder
if (mesajGonderici != null) {
mesajGonderici.println(sifrele(mesaj));
} else {
hataGoster("Bağlantı kurulmadı!");
}
}
mesajGirisi.setText("");
}
private void baslat() {
JPanel ayarPaneli = new JPanel(new GridLayout(4, 2));
JTextField sunucuAdresiAlani = new JTextField(VARSAYILAN_SUNUCU);
JTextField portAlani = new JTextField(String.valueOf(VARSAYILAN_PORT));
JTextField kullaniciAdiAlani = new JTextField();
JCheckBox sunucuModuSecimi = new JCheckBox("Sunucu olarak başlat");
ayarPaneli.add(new JLabel("Sunucu IP:"));
ayarPaneli.add(sunucuAdresiAlani);
ayarPaneli.add(new JLabel("Port:"));
ayarPaneli.add(portAlani);
ayarPaneli.add(new JLabel("Kullanıcı Adı:"));
ayarPaneli.add(kullaniciAdiAlani);
ayarPaneli.add(new JLabel("Mod:"));
ayarPaneli.add(sunucuModuSecimi);
int sonuc = JOptionPane.showConfirmDialog(null, ayarPaneli, "Bağlantı Ayarları", JOptionPane.OK_CANCEL_OPTION);
if (sonuc != JOptionPane.OK_OPTION) {
System.exit(0);
}
String sunucuAdresi = sunucuAdresiAlani.getText().trim();
int port;
try {
port = Integer.parseInt(portAlani.getText().trim());
} catch (NumberFormatException e) {
hataGoster("Geçersiz port numarası!");
System.exit(1);
return;
}
kullaniciAdi = kullaniciAdiAlani.getText().trim();
sunucuMu = sunucuModuSecimi.isSelected();
if (kullaniciAdi.isEmpty()) {
hataGoster("Kullanıcı adı boş olamaz!");
System.exit(1);
return;
}
try {
if (sunucuMu) {
istemciler = new HashMap<>();
cevrimiciKullanicilar = new HashSet<>();
sunucuSoketi = new ServerSocket(port);
sohbetAlani.append("Sunucu başlatıldı, port: " + port + "\n");
pencere.setTitle("Ana Sunucu");
new Thread(this::sunucuyuCalistir).start();
} else {
istemciSoketi = new Socket(sunucuAdresi, port);
mesajGonderici = new PrintWriter(istemciSoketi.getOutputStream(), true);
mesajOkuyucu = new BufferedReader(new InputStreamReader(istemciSoketi.getInputStream()));
pencere.setTitle("Main: " + kullaniciAdi);
new Thread(this::istemciyiCalistir).start();
}
pencere.setVisible(true);
} catch (IOException e) {
hataGoster("Bağlantı hatası: " + e.getMessage());
System.exit(1);
}
}
private void sunucuyuCalistir() {
try {
while (true) {
Socket istemci = sunucuSoketi.accept();
new Thread(() -> istemciyiYonet(istemci)).start();
}
} catch (IOException e) {
if (!sunucuSoketi.isClosed()) {
sohbetAlani.append("Sunucu hatası: " + e.getMessage() + "\n");
}
}
}
private void istemciyiYonet(Socket istemci) {
String istemciKullaniciAdi = null;
PrintWriter istemciGonderici = null;
BufferedReader istemciOkuyucu = null;
try {
istemciGonderici = new PrintWriter(istemci.getOutputStream(), true);
istemciOkuyucu = new BufferedReader(new InputStreamReader(istemci.getInputStream()));
while (true) {
istemciGonderici.println("KULLANICI_ADI_GONDER");
istemciKullaniciAdi = istemciOkuyucu.readLine();
if (istemciKullaniciAdi == null || istemciKullaniciAdi.trim().isEmpty()) {
return;
}
synchronized (istemciler) {
if (!istemciler.containsKey(istemciKullaniciAdi)) {
istemciler.put(istemciKullaniciAdi, istemciGonderici);
cevrimiciKullanicilar.add(istemciKullaniciAdi);
break;
} else {
istemciGonderici.println("KULLANICI_ADI_ALINMIS");
}
}
}
yayinYap(sifrele("SISTEM:" + istemciKullaniciAdi + " sohbete katıldı."));
yayinYap(sifrele("CEVRIMICI_KULLANICILAR:" + String.join(",", cevrimiciKullanicilar)));
sohbetAlani.append(istemciKullaniciAdi + " bağlandı.\n");
String sifreliMesaj;
while ((sifreliMesaj = istemciOkuyucu.readLine()) != null) {
String mesaj = coz(sifreliMesaj);
sohbetAlani.append(istemciKullaniciAdi + ": " + mesaj + "\n");
if (mesaj.startsWith("OZEL:")) {
String[] parcalar = mesaj.split(":", 3);
if (parcalar.length == 3) {
String alici = parcalar[1];
String ozelMesaj = parcalar[2];
synchronized (istemciler) {
PrintWriter aliciGonderici = istemciler.get(alici);
if (aliciGonderici != null) {
aliciGonderici.println(sifrele("OZEL:" + istemciKullaniciAdi + ":" + ozelMesaj));
}
istemciGonderici.println(sifrele("OZEL:" + istemciKullaniciAdi + ":" + ozelMesaj));
}
}
} else {
yayinYap(sifrele("MESAJ:" + istemciKullaniciAdi + ":" + mesaj));
}
}
} catch (IOException e) {
if (istemciKullaniciAdi != null) {
sohbetAlani.append(istemciKullaniciAdi + " bağlantısı koptu: " + e.getMessage() + "\n");
}
} finally {
if (istemciKullaniciAdi != null) {
synchronized (istemciler) {
istemciler.remove(istemciKullaniciAdi);
cevrimiciKullanicilar.remove(istemciKullaniciAdi);
}
yayinYap(sifrele("SISTEM:" + istemciKullaniciAdi + " sohbetten ayrıldı."));
yayinYap(sifrele("CEVRIMICI_KULLANICILAR:" + String.join(",", cevrimiciKullanicilar)));
sohbetAlani.append(istemciKullaniciAdi + " ayrıldı.\n");
}
try {
if (istemciOkuyucu != null) istemciOkuyucu.close();
if (istemciGonderici != null) istemciGonderici.close();
if (istemci != null) istemci.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void yayinYap(String sifreliMesaj) {
synchronized (istemciler) {
for (PrintWriter gonderici : istemciler.values()) {
gonderici.println(sifreliMesaj);
gonderici.flush();
}
}
}
private void istemciyiCalistir() {
try {
String sifreliMesaj;
while ((sifreliMesaj = mesajOkuyucu.readLine()) != null) {
String mesaj = coz(sifreliMesaj);
if (mesaj.equals("KULLANICI_ADI_GONDER")) {
mesajGonderici.println(kullaniciAdi); // Kullanıcı adı şifrelenmez
} else if (mesaj.equals("KULLANICI_ADI_ALINMIS")) {
hataGoster("Bu kullanıcı adı zaten alınmış!");
baglantiyiKes();
return;
} else if (mesaj.startsWith("MESAJ:")) {
String[] parcalar = mesaj.split(":", 3);
if (parcalar.length == 3) {
sohbetAlani.append(parcalar[1] + ": " + parcalar[2] + "\n");
}
} else if (mesaj.startsWith("OZEL:")) {
String[] parcalar = mesaj.split(":", 3);
if (parcalar.length == 3) {
sohbetAlani.append("[Özel] " + parcalar[1] + ": " + parcalar[2] + "\n");
}
} else if (mesaj.startsWith("SISTEM:")) {
sohbetAlani.append("[Sistem] " + mesaj.substring(7) + "\n");
} else if (mesaj.startsWith("CEVRIMICI_KULLANICILAR:")) {
String[] kullanicilar = mesaj.substring(23).split(",");
kullaniciListesiModeli.clear();
for (String kullanici : kullanicilar) {
if (!kullanici.isEmpty()) {
kullaniciListesiModeli.addElement(kullanici);
}
}
}
}
} catch (IOException e) {
hataGoster("Sunucu bağlantısı koptu: " + e.getMessage());
} finally {
baglantiyiKes();
}
}
private String sifrele(String mesaj) {
try {
SecretKeySpec anahtar = new SecretKeySpec(ANAHTAR.getBytes(), "AES");
Cipher sifreleyici = Cipher.getInstance("AES");
sifreleyici.init(Cipher.ENCRYPT_MODE, anahtar);
byte[] sifreliVeri = sifreleyici.doFinal(mesaj.getBytes());
return Base64.getEncoder().encodeToString(sifreliVeri);
} catch (Exception e) {
e.printStackTrace();
return mesaj; // Hata olursa şifresiz döner
}
}
private String coz(String sifreliMesaj) {
try {
SecretKeySpec anahtar = new SecretKeySpec(ANAHTAR.getBytes(), "AES");
Cipher cozucu = Cipher.getInstance("AES");
cozucu.init(Cipher.DECRYPT_MODE, anahtar);
byte[] sifreliVeri = Base64.getDecoder().decode(sifreliMesaj);
byte[] cozulmusVeri = cozucu.doFinal(sifreliVeri);
return new String(cozulmusVeri);
} catch (Exception e) {
e.printStackTrace();
return sifreliMesaj; // Hata olursa şifreli hali döner
}
}
private void hataGoster(String mesaj) {
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(pencere, mesaj, "Hata", JOptionPane.ERROR_MESSAGE));
}
private void baglantiyiKes() {
try {
if (mesajGonderici != null) mesajGonderici.close();
if (mesajOkuyucu != null) mesajOkuyucu.close();
if (istemciSoketi != null) istemciSoketi.close();
if (sunucuSoketi != null) sunucuSoketi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Main uygulama = new Main();
uygulama.baslat();
});
}
}
Kodlar bu kadardı şimdi arayüze bakalım;
[ Bağlantı Ayarları Belirleme Kısmı ]


[ Chat Arayüzü ]


Konu bu kadardı.
Görüşmek Üzere...

Son düzenleme: