<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ahmet Kakıcı &#187; tcp</title>
	<atom:link href="http://www.ahmetkakici.com/tag/tcp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ahmetkakici.com</link>
	<description>Blog</description>
	<lastBuildDate>Sun, 03 Apr 2011 10:48:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Java ile Sohbet Programı</title>
		<link>http://www.ahmetkakici.com/programlama/java-ile-sohbet-programi/</link>
		<comments>http://www.ahmetkakici.com/programlama/java-ile-sohbet-programi/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 20:49:17 +0000</pubDate>
		<dc:creator>Ahmet Kakıcı</dc:creator>
				<category><![CDATA[Programlama]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[socket]]></category>
		<category><![CDATA[tcp]]></category>
		<category><![CDATA[udp]]></category>

		<guid isPermaLink="false">http://www.ahmetkakici.com/?p=132</guid>
		<description><![CDATA[Sonunda uzun zamandır ertelediğim bu yazıyı da yayınladım ve kafamdan sildim. Aşağıda göreceğiniz kodlar basit bir sohbet programının kodlarıdır. Ayırca java&#8217;da soket programlama için de bir örnek teşkil etmektedir. Programı NetBeans ile yazdım ve NetBeans tarafından otomatik olarak eklenen kodlar aşağıda yer almamaktadır. Kodları ve programın işleyişini daha iyi anlayabilmeniz için bir takım terimleri ve [...]]]></description>
			<content:encoded><![CDATA[<p>Sonunda uzun zamandır ertelediğim bu yazıyı da yayınladım ve kafamdan sildim. Aşağıda göreceğiniz kodlar basit bir sohbet programının kodlarıdır. Ayırca java&#8217;da soket programlama için de bir örnek teşkil etmektedir. Programı NetBeans ile yazdım ve NetBeans tarafından otomatik olarak eklenen kodlar aşağıda yer almamaktadır.</p>
<p>Kodları ve programın işleyişini daha iyi anlayabilmeniz için bir takım terimleri ve yapıları bilmeniz gerektiğini düşünerekten öncelikle bu bilgileri verelim.</p>
<p><strong>Protokol Nedir?</strong></p>
<p>Herhangi bir ağ içerisinde bulunan cihazların birbirleriyle haberleşmeleri için bellirli protokoller tanımlanmıştır. Bu protokoller sayesinde kullanıcılar alt yapıdaki detaylarla uğraşmadan veri alışverişini gerçekletirebilir.<span id="more-132"></span></p>
<p>Farklı amaçlar için farklı protokoller geliştirilmiştir. Bu farklı protokollerin birbirlerine göre üstünlük ve zayıflıkları vardır. Kullanım alanına göre doğru protokol seçilmelidir.</p>
<p>Yaztığım programda User Datagram Protokol  &#8211; UDP protokolünü kullandım.  UDP protokolü veri iletişimini bağlantı kurmaksızın paketler gönderir. Bağlantı kurulmadığından dolayı protokolden mesajın iletildiğine dair herhangi bir bilgi edinilemez. Bu tip bir onay sistemi kullanıcı tarafından isteğe bağlı olarak ayrıca yazılmalıdır. UDP’de gönderilen paketlerin herhangi bir sıra numarası ve sırayla ulaşma garantisi de yoktur. Bu tip özellikler için ekstra başlık bigileri gerekmektedir, UDP bu başlık bilgilerini içermediğinden başlık bilgisi de diğer protokllere göre (ör:TCP) daha küçüktür. Başlık bilgilerinin küçük olması sayesinde UDP daha az bant genişliğine ihtiyaç duyar. Bu avantajından dolayı gerçek zamanlı ses veya görüntü iletişiminde tercih edilir.</p>
<p><strong>Port Nedir ?</strong></p>
<p>Portlar bir bilgisayarın ağda sahip olduğu IP adresinden dışarıya açılan birbirinden bağımsız kapılar olarak tanımlanabilir. Port numaraları 16bit ile ifade edildiğinden 65536 adet port mevcuttur. Herhangi bir uygulamanın kullanacağı port numarası seçilirken daha önceden başka bir programın bu portu kullanıp kullanmadığına dikkat edilmelidir. Aksi halde iki uygulama da düzgün çalışmayabilir.</p>
<p>UDP protokolünde veri iletişimi yapmak için IP ve PORT ikilisini kullanarak adresleme yapmak gerekir. Bu ikili kullanar bir soket yaratılır ve iletişim soket üzerinden yapılır.</p>
<p><strong>Soket Nedir ?</strong></p>
<p>Soket IP adresi ve Port birleşiminden oluşan uygulamalarda ağ içerisinde bulunan alt düzey ayrıntılarla uğraşmadan veri alışverişi yapmayı sağlayan ve unix sistemlerde bulunan dosya yapısına benzer bir yapıdır.  TCP/IP protokolünde mevcut olan soketler uygulama seviyesinde bağlantıları simgelemeye yarar.</p>
<p>Yaygın olarak kullanılan iki türlü soket yapısı mevcuttur. Bunlardan biri SOCK_STREAM ile tanımlanan ve streaming yapmaya yarıyan soket tipidir. Bu soket yapısında bağlantılı (connection oriented) haberleşme kullanılır. Yani haberleşme sırasında aktif olan bağlantı ve soket yapısı mevcuttur. TCP protokolü SOCK_STREAM tipinde soketler üzerinden haberleşme yapar. Bu soketlerden yapılan iletişim tamamen güvenlidir. Yani yanlış veri iletimi olması durumunda protokolden dolayı sistem kararlı ve doğru veriyi iletene kadar tekrar gönderme/isteme işlemini yapar. Ayrıca bu soketler üzerinden gönderilern verilerin alıcı tarafa da aynı sırayla ulaşacağı garanti edilmiştir. “A” ve “B” datasını içeren iki mesajı gönderdiğimizde alıcı tarafta yine “A” ve “B” sırasıyla alınacağı garanti edilmiştir.</p>
<p>Diğer bir soket türü ise SOCK_DGRAM ile tanımlanan datagram tipi soketlerdir. TCP’ye göre güvensiz veri iletişimi yapar. Bunun nedeni gönderilerecek datayı UDP protokolü üzerinden yollaması ve paketi bir kez ağa bıraktıktan sınra herhangi bir takip işlemi yapmamasıdır. Yani kullanıcıya verinin ulaşıp ulaşmadığına dair herhangi bir bilgi sağlamaz. Buna karşılık alıcıdan onay mesajı yollatarak iletimi biraz daha olsun kararlı hale getirebilinir. Bu soketin tercih edilme sebebi ise stream türünde yayınlardır. Her ne kadar streaming soket “streaming” için daha uygun gibi görünsede datagram tipi soketler bu iş için daha uygundur. Bunun sebebi kayıp paketlerin tekrar yollanması, aşırı başlık bilgisi, çok bant genişliği harcaması, bağlantının sürekli olarak aktif kalması gibi dezavantajlarından dolayı datagram soketler streaming işlemi için tercih edilmektedir.</p>
<p><strong>Paket Nedir ?</strong></p>
<p>UDP ile bağlantısız haberleşme yapıldığından veriler birbirinden bağımsız paketler ile gönderilir. TCP protokolünde bağlantılı haberleşme yapıldığından veri iletişimi başlarken bir bağlantı kurulur ve sürekli olarak bu bağlantı üzerinden haberleşme sağlanır. Veri iletişimi olmasa dahi bağlantı açık kalır. UDP  protokolü için Java dilinde belirlenen paket değişken tipi  Datagram Packet’dir.  Her bir paket içerisinde gönderilecek veri ve paketteki veri miktarını belirten değişkenler vardır. Bunun yanı sıra paketi gönderdiğimiz bilgisayarın IP adresi ve port numarası da pakete dahil edilmelidir.</p>
<p>Gönderici ve alıcı adresleri de UDP paketinin içinde olmasına rağmen bu paketler tek başına iletişim için yeterli değildir. UDP paketleri de ağda iletim için IP protokolünü kullanır. Bundan dolayı her paketin başına IP başlık bilgileri de eklenir. Aşağıdaki şekilde bir IP başlığı ve altında ise UDP paketinin temel yapısı gösterilmiştir:</p>
<p><a class="thickbox" href="http://www.ahmetkakici.com/wp-content/gallery/java-sohbet/paket.jpg"><img class="ngg-singlepic ngg-center" src="http://www.ahmetkakici.com/wp-content/gallery/java-sohbet/paket.jpg" alt="paket.jpg" /></a></p>
<p><a class="thickbox" href="http://www.ahmetkakici.com/wp-content/gallery/java-sohbet/udp.jpg"><img class="ngg-singlepic ngg-center" src="http://www.ahmetkakici.com/wp-content/gallery/java-sohbet/udp.jpg" alt="udp.jpg" /></a></p>
<p><strong>Programın Genel Yapısı</strong></p>
<p>Program sunucu/istemci mimarisine dayanarak çalışmaktadır. İstemci kısmı Applet olarak yazıldı ve web üzerinden sohbet edebilme imkanı sağlamaktadır. Sunucu kısmı ise masaüstü uygulaması olarak yazılmıştır. Sunucu çalışmaya başlar başlamaz ilgili portu dinleyerek gelen paketleri değerlendirerek mesajları istemciler arasında iletmektedir. İstemciler birbirleri arasında direk mesajlaşmak yerine sunucu üzerinden mesajlaşmaktadır. Bundan dolayı istemcilerde diğer istemcilerin adresleri yerine sadece isimleri tutulmaktadır.</p>
<p><strong>İstemci Tarafı</strong></p>
<p>İstemci kodu iki temel sınıftan oluşmaktadır. ClientMsgHandler ve ClientGUI. ClientMsgHandler veri iletim fonksiyonlarını içermektedir. ClientGUI ise arayüzü ve ClientMsgHandler’dan gelen verileri kullanıcıya göstermektedir. ClientMsgHandler thread sınıfını implement ederek oluşturulmuştur. Bu sayede arayüzde herhangi bir takılma olmadan veri iletişim işlemleri eş zamanlı olarak yapılmaktadır.</p>
<p>Programda iki türde istemci vardır. Birincisi sunucu üzerinde çalışan ve web üzerinden hizmet veren istemcidir. Web üzerinden sunucuya bağlanan istemciler için yazılmıştır ve sunucu adresini bilmeksizin her istemci bu sunucuya bağlanabilir. Diğer istemci türünde ise istemci kodu bilgisayara indirilip web tarayıcısı üzerinden local olarak çalıştırılabilir. Bu istemcide ise sunucunun ip adresini de ayrıca bilmek gerekmektedir.</p>
<p><strong>İstemci Tarafındaki Sınıflar ve Fonksiyonları</strong></p>
<p><strong>ClientMsgHandler</strong> sınıfına ait fonksiyonlar:<br />
<strong>Send:</strong>String tipinde tutulan gönderilecek mesajı byte dizisine çevirir. Daha sonra DatagramSocket üzerinden yollamak üzere yeni bir PatagramPacket hazırlayak oluşturulan byte dizsini, alıc adresini ve iletişimde kullanılacak port numarasını da pakete ekler. Son olarak paketi DatagramSocket üzerinden gönderir.</p>
<p><strong>Recieve</strong>: DatagramSocket üzerinden gelen paketi alabilmek için yeni bir DatagramSocket yaratır. Okunan veriyi bu pakete yazdıktan sonra mesaj kısmını byte dizisinden string tipine çevirir. Daha sonra mesajı işlemek üzere ParseMsg ve HandleMsg fonkisyonlarını çağırır.</p>
<p><strong>SetHost</strong>: Parametre olarak host adresini alıp bu adresi InetAddress türüne çevirir.<br />
<strong></strong></p>
<p><strong>BuildMsg</strong>: Parametre olarak aldığı mesaj türüne göre gönderilecek mesajı string olarak oluşturur. String türündeki mesajın formatı aşağıdaki gibidir:<br />
gönderici_adı  &gt; alıcı_adı &gt; mesaj_türü &gt; mesaj_içeriği<br />
Bu yapıda “&gt;” sembolü ayraç olarak kullanılmıştır.<br />
Mesaj türleri ise aşağıdaki şekildedir:</p>
<p><strong>ADD_ME</strong> – Kullanıcı ekleme<br />
<strong>REMOVE_ME</strong> – Kullanıcı silme<br />
<strong>SEND_MSG</strong> – Normal mesaj<br />
<strong>GET_USERS</strong> – Kullanıcı listesi isteği<br />
<strong>ACK_MSG</strong> – Onay mesajı</p>
<p><strong>ParseMsg</strong>: Alınan mesajı “&gt;” ayracına göre bölümleyerek mesajın içeriğini gerekli değişkenlere atar.</p>
<p><strong>HandleMsg</strong>: Parse edilen mesajın türüne bağlı olarak işlemleri gerçekleştirir.  Mesaj türlerine göre yaptığı işlemler aşağıdaki gibidir:<br />
<strong></strong></p>
<p><strong>SEND_MSG</strong>: Gelen mesajı arayüzde göstermek üzere ClientGUI sınıfına gönderir.<strong></strong></p>
<p><strong>REMOVE_ME</strong>: Gelen kullanıcı adını ClientGUI’de gösterilen listeden silmek üzere ClientGUI sınıfına iletir. Aynı zamanda istemcilerin tutulduğu vector yapısından ilgili istemciyi silmesi için RemoveClient fonksiyonuna kullanıcı adını iletir.<strong></strong></p>
<p><strong>ACK_MSG</strong>: Bağlantının kurulduğunu onaylayan bu mesaj alındığı zaman arayüzde gerekli değişiklikler yapılarak mesaj iletimine uygun yapı oluşturulur.<strong></strong></p>
<p><strong>ADD_ME</strong>: Gelen kullanıcı adını istemcilerin tutulduğu vector yapısına ekler ve arayüz sınıfının da bu kullanıcı adını göstermesini sağlar.<strong></strong></p>
<p><strong>GET_USERS</strong>: Kullanıcı isteğinin karşılığı niteliğindedir. İlk  kez bağlantı kuruluduğunda liste alınarak arayüzde gösterilir. Aynı zamanda istemcilerin her birini vector yapısına ekler. Bu mesaj alındıktan sonra bağlantı tamamlanmış ve kullanıcı listesi alınmış olduğundan dolayı mesaj dinleme işlemini başlatacak thread çalıştırılr. Sonsuz bir döngü içinde ilgili port sürekli olarak dinlenir.</p>
<p><strong>Connect</strong>: ClientGUI’den alınan kullanıcı adını içeren bir mesaj ile sunucuya bağlantı isteğini gönderir. Send methodunu çağırarak mesajın iletimini sağlar, daha sonra Recieve methoduyla bağlantı isteğine gelcek cevabı bekler. Cevap gelmeme ihtimaline karşı soket’in bloklanma süresi 2sn olarak ayarlanmıştır. Sunucundan cevap alınırsa veya soket süresi dolarsa bağlantı kurulamadığı ClientGUI’de gösterilir ve soket’in bloklanma süresi tekrar sıfıra setlenir (sonsuz).</p>
<p><strong>Disconnect</strong>: Sunucuylya yapılan bağlantının bitirilmesi isteğini gönderir. Bu sayede bağlantıyı kapatan istemciler diğer istemcilerin listesinden silinecektir. UDP gibi bağlantısız bir iletişim protokolü kullanıldığından dolayı bu işlem gereklidir. Aksi halde sunucu  &#8211; istemci arasında sürekli ping gönderek her iki tarafında hala hatta olduğu kontrol edilmelidir.</p>
<p><strong>GetClientList</strong>: Sunucu ile ilk defa bağlantı kurulduğu zaman varolan istemcilerin listesini almak için gerekli mesajı oluşturup gönderir ve cevabı alır. Kullanıcı listesi alınmadan önce ilgili port ayrı bir thread ile dinlenmediği için bu fonksiyon içinden Recieve fonkisyonu çağrılmıştır.</p>
<p><strong>BuildClientList</strong>:  Sunucu istemciye diğer istemcilerin isim listesini gönderirken isimleri “|” ayracı ile ayırır. HandleMsg fonksiyonu bu ayraça göre gelen veriyi bölerek BuildClientList fonksiyonuna string dizisi olarak iletir. BuildClientList fonksiyonu ise gelen bu diziyi vector yapısına çevirerek kaydeder. Vector yapısı kullanılmasının amacı istemci sayısının dinamik olarak değişmesi ve ClientGUI’de ki listede istemcilerin kolaylıkla gösterilmesidir.</p>
<p><strong>RemoveClient</strong>: Herhangi bir istemci sunucuya ayrıdığını bildirdiğinde sunucu geride kalan bütün istemcilere bu mesajı iletir ve istemciler bu fonksiyon ile ayrılan istemcinin adını vector yapısından ve ClientGUI’de kullanılan listeden siler.</p>
<p><strong>ClientGUI </strong>sınıfına ait fonkisyonlar:</p>
<p><strong>SendMessage</strong>: TextField2’ye girilen mesajı ve JList1’den seçilen kullanıcı adını ClientMsgHandler sınıfına göndererek mesajın sunucuya iletilmesini sağlar.</p>
<p><strong>AddMessage</strong>: ClientMsgHandler tarafından alınan mesajları jTextArea’ya kimden geldiğini göstererek ekler.</p>
<p><strong>UpdateUserList</strong>: Sunucuya herhangi bir istemci bağlandığında veya ayrıldığında arayüzde gösterilen istemci isimlerini yeniler.</p>
<p><strong>SetStatus</strong>: Sunucuya bağlanıp bağlanılmadığını ve mesaj gönderirken hangi kullanıcının seçildiğini jTextFeild3’e yazdırır.</p>
<p><strong>Connect</strong>: Bağlan butonuna basıldığı zaman kullanıcıdan alınan ip adresi (veya host adı) ve kullanıcı adıyla sunucuya bağlanmak için ClientMsgHandler’da bulunan Connect fonksiyonun çağırır.</p>
<p><strong>Destroy</strong>: Kullanıcı tarayıcıyı kapattığı zaman sunucuya bağlantıyı sonlandırma mesajını gönderir.</p>
<p><strong>Sunucu Tarafı </strong></p>
<p>Sunucu işlemleri genel olarak istemcilerin listesini tutmak ve gelen mesajları iletmek üzerine kuruludur.  ClientHandler sınıfı sürekli olarak ilgili portu dinleyerek mesaj iletim işini üstlenmektedir. Onun haricinde serverGUI mesajlaşmaların ve sisteme gelip giden istemcilerin özetini gösteren bir arayüz oluşturmaktadır.</p>
<p><strong>ClientHandler </strong>sınıfına ait fonksiyonlar:<br />
<strong></strong></p>
<p><strong>BuildMsg</strong>: Parametre olarak aldığı mesaj türüne göre gönderilecek mesajı string olarak oluşturur. String türündeki mesajın formatı aşağıdaki gibidir:<br />
gönderici_adı  &gt; alıcı_adı &gt; mesaj_türü &gt; mesaj_içeriği<br />
Bu yapıda “&gt;” sembolü ayraç olarak kullanılmıştır.<br />
Mesaj türleri ise aşağıdaki şekildedir:<br />
<strong></strong></p>
<p><strong>ADD_ME</strong> – Kullanıcı ekleme<br />
<strong>REMOVE_ME</strong> – Kullanıcı silme<br />
<strong>SEND_MSG</strong> – Normal mesaj<br />
<strong>GET_USERS</strong> – Kullanıcı listesi isteği<br />
<strong>ACK_MSG</strong> – Onay mesajı</p>
<p><strong>ParseMsg</strong>:  Alınan mesajı “&gt;” ayracına göre bölümleyerek mesajın içeriğini gerekli değişkenlere atar.</p>
<p><strong>HandleMsg</strong>: Parse edilen mesajın türüne bağlı olarak işlemleri gerçekleştirir.  Mesaj türlerine göre yaptığı işlemler aşağıdaki gibidir:<br />
<strong></strong></p>
<p><strong>SEND_MSG</strong>: Mesaj gönderilecek istemcinin adını clients vector yapısı içinde arar. Bulduğu elemandan adresi alarak mesajı  ilgili istemciye gönderir.  Ayrıca sunucu arayüzünde de mesajı ve kimden kime gönderildiğini yazar.<br />
<strong></strong></p>
<p><strong>REMOVE_ME</strong>:  İstemci sunucudan ayrıldığı zaman client vector yapısı içinden bu istemciyi siler ve diğer tüm istemcilere ilgili istemci adını yollayarak listelerinden silmesini bildirir. Buna ek olarak sunucu arayüzünde de çıkan istemcinin adını yazar.</p>
<p><strong>ADD_ME</strong>: Yeni istemcinin adını ve adresini arayüzde gösterir. Daha sonra istemcilerin tutulduğu vektöre yeni bir istemci sınıfı nesnesi yaratıp ekler. Bundan sonra ise istemciye bağlantının kabul edildiğine dair bir onay mesajı yollar. Yeni gelen kullanıcıya onay mesajı gönderip bağlantıyı kabul ettikten sonra önceden bağlanan istemcilere yeni gelen istemcinin adını gönderir.</p>
<p><strong>GET_USERS</strong>:  Bu mesajdan sonra sunucu mesajı gönderen istemciye o anda bağlı olan istemcilerin isimlerini gönderir. İsimler birbirinden “|” ayracı ile ayrılmıştır.</p>
<p><strong>ServerSend</strong>: Gönderilecek mesajı byte dizisine çevirerek datagram paketi içine koyar ve datagram soketi üzerinden gönderir.</p>
<p><strong>ServerRecieve</strong>: İlgili portu dinleyerek gelen mesajları string tipine çevirir. Ayrıca gönderenin adresini de datagram paketinden çıkararak kaydeder.</p>
<p><strong>NotifyAllClients</strong>:  Belirlenen mesajı o anda bağlı olan istemcilerin hepsine gönderir.</p>
<p><strong>BuildClientList</strong>: Bağlı olan istemcilerin isimlerini bir string’de birleştirerek mesajı gönderilmeye hazır hale getirir.</p>
<p><strong>GetReceiverAddressByName</strong>: Sunucuya gelen mesajlarda sadece gönderilecek istemcinin adı bulunmaktadır. Adresler ise sunucuda tutulan clients vector yapısındadır. Bu fonksiyon mesaj gönderilecek istemcinin adını vector elemanlarıyla karşılaştırıp ilgili adresi bulur.</p>
<p><strong>RemoveClient</strong>: Parametre olarak aldığı kullanıcı adını clients vector yapısında arar ve ilgili istemciyi  vector’den siler. Daha sonra geride kalan istemcilere bu silme işlemini bildirir.</p>
<pre class="brush: java; title: ; notranslate">

/**
*
* @author Ahmet
*/
import java.io.*;
import java.net.*;
import java.util.*;

public class clientMsgHandler extends Thread{

private DatagramSocket socket;
private DatagramPacket giden;
private DatagramPacket gelen;
private InetAddress address;

private int msgType;
private String received;
private String[] parsedMsg;
public String myName;
public String message;
public String receiverName;
public String senderName;

private static final int PORT = 4444;
private static final String MSG_SEPERATOR = &quot;&gt;&quot;;
private static final int ADD_ME=0;
private static final int REMOVE_ME=1;
private static final int SEND_MSG=2;
private static final int GET_USERS=3;
private static final int ACK_MSG = 4;
public clientGUI parent;

public boolean connected = false;
public String hostname;
public String msg2send;
public Vector clients = new Vector();

public clientMsgHandler(String argHostname) throws IOException{
hostname = argHostname;
address = InetAddress.getByName(hostname);
socket = new DatagramSocket();
socket.setSoTimeout(0);
}

@Override
public void run(){
while(true){
try{
Recieve();
socket.setSoTimeout(0);
}catch(Exception e){}
}

}
public void SetHost(String argHostname) throws UnknownHostException{
hostname = argHostname;
address = InetAddress.getByName(hostname);
}
private void Send(){
byte[] buf = new byte[msg2send.length()];
buf = msg2send.getBytes();
giden = new DatagramPacket(buf, buf.length, address, PORT);
try{
socket.send(giden);
}catch(Exception e){}
System.out.println(&quot;Giden mesaj: &quot; + msg2send);
}

public void Recieve(){
byte[] buf = new byte[256];
gelen = new DatagramPacket(buf, buf.length);
try{
socket.receive(gelen);
}catch(Exception e){}
received = new String(gelen.getData(), 0, gelen.getLength());
System.out.println(&quot;Gelen mesaj: &quot; + received);
ParseMsg();
HandleMsg();
}

private void BuildMsg(int argFlag){
msg2send = myName+MSG_SEPERATOR+receiverName+MSG_SEPERATOR+argFlag+MSG_SEPERATOR+message;
}

public void SendMsg(){
BuildMsg(SEND_MSG);
Send();
}

public void ParseMsg(){

try {
parsedMsg = received.split(MSG_SEPERATOR);
senderName = parsedMsg[0];
msgType = Integer.parseInt(parsedMsg[1]);
message = parsedMsg[2];
} catch (Exception exception) {
parent.SetStatus(&quot;Bağlantı kurulamadı.&quot;);
msgType = -1;
message = &quot;&quot;;
}
}

public void Connect(){
try {
message = myName;
receiverName = &quot;Server&quot;;
BuildMsg(ADD_ME);
Send();
socket.setSoTimeout(2000);
Recieve();
socket.setSoTimeout(0);

} catch (SocketException ex) {}
}

public void Disconnect(){
receiverName= &quot;Server&quot;;
BuildMsg(REMOVE_ME);
Send();
connected=false;
}

public void HandleMsg(){
if(msgType==SEND_MSG){
parent.AddMessage(message,senderName);
}
else if(msgType==REMOVE_ME){
RemoveClient(message);
parent.UpdateUserList();
}
else if(msgType==ACK_MSG){
connected=true;
}
else if(msgType==ADD_ME){
clients.add(message);
parent.UpdateUserList();
}
else if(msgType==GET_USERS){
String[] clientList = parsedMsg[2].split(&quot;\\|&quot;);
BuildClientList(clientList);
start();
}
}

public void GetClientList(){
message = myName;
BuildMsg(GET_USERS);
Send();
Recieve();
}

private void BuildClientList(String[] clientList){
clients.removeAllElements();
for (int i = 0; i &lt; clientList.length; i++) {
if(!myName.equalsIgnoreCase(clientList[i].toString()))
clients.add(clientList[i]);
}
}

private void RemoveClient(String argName){
for (int i = 0; i &lt; clients.size(); i++) {
String tmp = (String) clients.elementAt(i);
if (tmp.equals(argName)) {
clients.remove(i);
break;
}

}

}

}
</pre>
<pre class="brush: java; title: ; notranslate">

import java.io.IOException;

/*
* clientGUI.java
*
* Created on 16 Nisan 2008 Çarşamba, 21:26
*/
import java.net.UnknownHostException;
import javax.swing.JOptionPane;

/**
*
* @author  Ahmet
*/
public class clientGUI extends javax.swing.JApplet {

private clientMsgHandler tr;

private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
// Kullanıcı adı girişi
Connect();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// Bağlan butonu
Connect();
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// Gönderme işlemi
int selected = jList1.getSelectedIndex();
if(selected&gt;-1)
SendMessage();
jTextField2.requestFocusInWindow();
}

private void jTextField2ActionPerformed(java.awt.event.ActionEvent evt) {
// Gönderme işlemi
int selected = jList1.getSelectedIndex();
if(selected&gt;-1)
SendMessage();
}

private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {
// Listeden kişi seçildiğinde:
jTextField3.setText(jList1.getSelectedValue().toString());
jButton2.setEnabled(true);
}

private void jTextField1FocusGained(java.awt.event.FocusEvent evt) {
// Kullanıcı adı girişi
if(jTextField1.getText().equalsIgnoreCase(&quot;Kullanıcı Adı&quot;))
jTextField1.setText(&quot;&quot;);
}

private void jTextField4FocusGained(java.awt.event.FocusEvent evt) {
// Server IP
if(jTextField4.getText().equalsIgnoreCase(&quot;Server IP&quot;))
jTextField4.setText(&quot;&quot;);
}

public void SendMessage(){
tr.message = jTextField2.getText();
tr.receiverName = jList1.getSelectedValue().toString();
tr.SendMsg();
AddMessage(tr.message,tr.myName);
jTextField2.setText(&quot;&quot;);
}

public void AddMessage(String argMsg, String argSender){
jTextArea1.append(&quot;\n&quot; + argSender + &quot;:&quot; + argMsg);

}

public void UpdateUserList(){
jList1.removeAll();
jList1.setListData(tr.clients);
}

public void Connect(){
try {
tr.myName = jTextField1.getText();
tr.SetHost(jTextField4.getText());
tr.Connect();
if (tr.connected) {
jList1.setVisible(true);
jTextField2.setVisible(true);
jButton2.setVisible(true);
jTextField1.setEnabled(false);
jTextField4.setEnabled(false);
tr.GetClientList();
jList1.setListData(tr.clients);
jButton1.setEnabled(false);
SetStatus(&quot;Bağlantı Kuruldu&quot;);
}
} catch (UnknownHostException ex) {

}
}

public void SetStatus(String argMsg){
jTextField3.setText(argMsg);
}

}
</pre>
<pre class="brush: java; title: ; notranslate">

class ClientHandler extends Thread{

private static final int PORT = 4444;
private static final int BUFFER_LENGTH = 256;
private static final String MSG_SEPERATOR = &quot;&gt;&quot;;

private static final int ADD_ME=0;
private static final int REMOVE_ME=1;
private static final int SEND_MSG=2;
private static final int GET_USERS=3;
private static final int ACK_MSG = 4;

public Vector clients = new Vector();
protected DatagramSocket socket = null;

String receivedMsg;					// Parse edilmemis mesaj
private String message;					// Mesajin icerigi - yazi
private int msgType;					// Mesaj turu
private String msg2send;				// Gonderilecek mesaj
private SocketAddress receiverAdress;                   // Mesajin gidecegi adres
private SocketAddress senderAddress;                    // Mesajin geldigi adres
private String receiverName;                            // Mesajin gidecegi kisi
private String senderName;                              // Mesaj gonderen kisi
public ServerGUIView parent;

@Override
public void run(){
while(true){
try{
ServerReceive();
ParseMsg();
HandleMsg();
}catch(Exception e){}

}
}

public ClientHandler() throws IOException {
super(&quot;ClientHandler&quot;);
socket = new DatagramSocket(PORT);
}

public void RemoveClient(String argName){
for(int i=0;i&lt;clients.size();i++){
Client tmp = (Client)clients.get(i);
if (tmp.clientName.equals(argName)){
clients.remove(i);
break;
}
}
}

public void GetReceiverAddressByName(){
for(int i=0;i&lt;clients.size();i++){
Client tmp = (Client)clients.get(i);
if (tmp.clientName.equalsIgnoreCase(receiverName)){
receiverAdress = tmp.clientAddress;
break;
}
}
}
private void BuildClientList(){
message = &quot;&quot;;
for(int i=0;i&lt;clients.size();i++){
Client tmp = (Client)clients.get(i);
message += tmp.clientName+&quot;|&quot;;
}

}

private void NotifyAllClients(){
message = senderName;
senderName = &quot;Server&quot;;
for(int i=0;i&lt;clients.size();i++){
Client tmp = (Client)clients.get(i);
if (!tmp.clientName.equalsIgnoreCase(message)){
receiverAdress = tmp.clientAddress;

ServerSend();
}

}
}

private void BuildMsg(int argFlag){
msg2send = senderName+MSG_SEPERATOR+argFlag+MSG_SEPERATOR+message;
}

public void ServerReceive()throws IOException{
byte[] buffer = new byte[BUFFER_LENGTH];
DatagramPacket gelenPaket = new DatagramPacket(buffer, BUFFER_LENGTH);
try{
socket.receive(gelenPaket);
}catch(Exception e){}
receivedMsg = new String(gelenPaket.getData(), 0, gelenPaket.getLength());
senderAddress = gelenPaket.getSocketAddress();
}

public void ServerSend(){
try{
byte[] buffer = new byte[msg2send.length()];
buffer = msg2send.getBytes();
DatagramPacket gidenPaket = new DatagramPacket(buffer, buffer.length, receiverAdress);
socket.send(gidenPaket);
}
catch(Exception e){

}
}

private void ParseMsg(){
String[] parsedMsg = receivedMsg.split(MSG_SEPERATOR);
senderName = parsedMsg[0];
receiverName = parsedMsg[1];
msgType = Integer.parseInt(parsedMsg[2]);
message = parsedMsg[3];
}

public void HandleMsg()throws IOException{
if(msgType==ADD_ME){
parent.AddTextarea(&quot;Yeni kullanici: &quot; + message + &quot;, adresi:&quot; + senderAddress+&quot;\n&quot;);
clients.add(new Client(message,senderAddress));
receiverAdress = senderAddress;
BuildMsg(ACK_MSG);
ServerSend();
BuildMsg(ADD_ME);
NotifyAllClients();
}
else if(msgType==SEND_MSG){
GetReceiverAddressByName();
parent.AddTextarea(senderName + &quot; -&gt; &quot; + receiverName + &quot; mesaj gonderiyor :'&quot; + message + &quot;'\n&quot;);
BuildMsg(SEND_MSG);
ServerSend();
}
else if(msgType==REMOVE_ME){
parent.AddTextarea(senderName + &quot;, bağlantıyı sonlandırdı.\n&quot;);
RemoveClient(senderName);
message = senderName;
BuildMsg(REMOVE_ME);
NotifyAllClients();
}
else if(msgType==GET_USERS){
parent.AddTextarea(senderName+&quot; kullanicisina liste yollaniliyor.\n&quot;);
BuildClientList();
senderName = &quot;Sunucu&quot;;
receiverAdress = senderAddress;
BuildMsg(GET_USERS);
ServerSend();
}
}
}

class Client{
String clientName;
SocketAddress clientAddress;

public Client(String argName,SocketAddress argAddress){
clientName = argName;
clientAddress = argAddress;
}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkakici.com/programlama/java-ile-sohbet-programi/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
	</channel>
</rss>

