|
Temel Bir Sohbet Yazılımı |
|
Gönderiliyor lütfen bekleyin... |
|
|
Sohbet programları haberleşmek için Winsock API’leri kullanır. Fakat sohbet
programları gibi ağ uygulamaları geliştirmek için saf API kullanmak zahmetlidir.
Bunun yerine MFC’nin CSocket sınıfını kullanacağız. CSocket sınıfı, CAsyncSocket
sınıfından türemiştir ve CAsyncSocket’e göre WinsockAPI’den daha fazla soyutlanma
sağlar. Genelde uygulamalarda doğrudan CSocket’i kullanmak yerine, CSocket’ten
türetilmiş özel sınıflar kullanılır. CAsyncSocket’e ait olan Accept, Receive,
Send gibi sanal işlevler amaca göre değiştirilir.
Sohbet programlarında iletişim TCP/IP tabanlı olduğu için bir sunucuya ve istemciye
ihtiyaç vardır. İstemciler, dinleme durumundaki sunucunun IP adresi bilgisini
kullanarak sunucuya bağlanır ve bilgi aktarımı sağlanır. Bundan dolayı sunucu
ve istemci programımızı ayrı ayrı yazacağız.
Uygulama
Sunucu ve istemci programlarımızı geliştirirken aşağıdaki adımlar ortaktır.
Öncelikle Visual C++ Projects kısmından MFC Application seçilmeli, proje özelliklerinden
de uygulamanın dialog tabanlı olduğu ve Windows Sockets kullandığı belirtilmelidir.
Şekil
1 - Proje türü
Proje oluşturulduktan sonra kendi soket sınıfımızı
oluşturmak için, ana menüde Project’e tıklayarak Add Class seçilmeli. Bunu yaptıktan
sonra, eklemek istediğimiz sınıfın adını, türetileceği taban sınıfı ve hangi
dosyanın içine kaydedileceğini belirtebileceğimiz bir dialog açılacaktır. Soket
sınıfımızı CSocket’ten türeteceğimizi şu şekilde belirtebiliriz:
Şekil 2 - CSocket’ten türemiş sınıf
oluşturma
Türetilen bu sınıfın istemci için tasarımı:
class
sohbetSoket : public CSocket
{
public:
sohbetSoket();
virtual ~sohbetSoket();
virtual void OnAccept(int nErrorCode);
virtual void OnClose(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnReceive(int nErrorCode);
virtual void OnSend(int nErrorCode);
void alinanlariAt(CEdit *sAlinan);
CEdit *alinan;
CString buf;
}; |
şeklinde olacak, ve sunucu versiyonunda fazladan sadece
sohbetSoket
*kabul;
satırını içerecektir. Bu yeni türettiğimiz sınıfı ana dialog sınıfı
içinde kullanacağımız için başlık dosyasına:
#include"sohbetSoket.h"
satırını
eklemeliyiz. Programımızın tasarımını Şekil 3’deki gibidir. Şekil 3’deki
kontrollerin üzerine tıkladığınızda, tıkladığınız kontrolün ID’sini ve atanacak
değişkeni görebilirsiniz.
Şekil 3
- Projenin görünümü ve kontrollere atanan değişkenler
Her iki formda da ortak olan değişkenlerden port isimli değişken, haberleşmenin
hangi porttan yapılacağını belirtir. alinan isimli metin kutusu karşı taraftan
alinanlari barindirmak için vardır. Gönder düğmesine basılınca metin isimli
metin kutusundaki yazılanlar gönderilir.
Sunucu ve istemci sınıfının üye değişkenleri şunlardır:
bool
bagli; //sadece istemci sınıfında
bool dinlemede; //sadece sunucu sınıfında
TSoket soket;
//kontrollere atanan otomatik oluşturulmuş değişkenler:
CString adres;
UINT port;
CString alinan;
CString metin; |
Öncelikle hem
sunucu hem de istemci için TSoket sınıfına, Receive işlevi ile aldığı paketleri
hangi kontrole atacağını, ana dialogun OnInitDialog işlevinde şu şekilde bildirmeliyiz:
soket.alinanlariAt((CEdit*)GetDlgItem(IDC_ALINAN)); |
TSoket sınıfının alinanlaraAt işlevini daha sonra açıklayacağız. Sunucu tarafında
Dinle düğmesine tıklandığında işletilecek kodu yazarak devam edelim:
//Bağlan/Kop
if(!dinlemede)
{
UpdateData();
soket.Create(port);
soket.Bind(port);
soket.Listen();
dinlemede = true;
SetWindowText("Sunucu - Aktif");
SetDlgItemText(IDC_DINLE,"Vazgeç");
}
else
{
soket.Close();
SetWindowText("Sunucu - Aktif değil");
bagli = false;
dinlemede = false;
SetDlgItemText(IDC_DINLE,"Dinle");
} |
UpdateData
işlevi port için belirtilen değeri kontrolden değişkene atmak için kullanıldı.
Sunucu tarafı soketi oluşturmak için kullanılan Create işlevi, parametre olarak
port numarasını alır. İstemci için soketin yaratılması sırasında parametre verilmez.
Bind işlevi, uygulamamızın, aktif olarak çalışılan makineye -parametre olarak
verilen porttan yapılan- bütün bağlantıları üstlenmesini sağlar. Yani Bind(x)
işlevinin çağrılması ile x portunda yapılan bütün bağlantıları programımız ele
alacaktır. Son olarak Listen işlevi ile dinleyeme, belirtilen porttan yapılacak
bağlantıları izlemeye başlayabiliriz. Fakat uygulamamız dinlemede ise Close
işlevi ile soketi durdurmuş ve kendisine yapılan referansları geçersiz kılmış
oluyoruz. CAsyncSocket sınıfının yokedicisi bu işlevi bizim için otomatikman
çağırır. Kodda geçen diğer işlevler ise dinlemede olup olmadığımız bilgisini
görüntülemek için kullanılmaktadır. TSoket sınıfının tasarımına geçmeden önce,
sınıfın sunucuya özel olan OnAccept işlevini de açıklayalım:
kabul = new TSoket();
kabul->alinanlariAt(alinan);
Accept(*kabul);
CSocket::OnAccept(nErrorCode); |
Sunucu soketlerde OnAccept işlevi sunucuya bir bağlantı yapıldığında otomatik
olarak çağrılır. Gelen bağlantıyı kabul etmek için Accept işlevini çağırmalı
ve parametre olarak da bu bağlantıyla yapılacak olan bütün transferleri kontrol
edecek bir soket verilmelidir. Bu soketin kalıcı olması için TSoket sınıfına
üye bir değişken olarak tanımlanmalıdır.
Gönder
düğmesine tıklandığında yapılacaklar ise şu şekildedir:
UpdateData();
if(!metin.IsEmpty())
{
for(UCHAR a=0; a<256-metin.GetLength();a++ )metin+=’%’;
soket.kabul->Send(metin.GetBuffer(),metin.GetLength());
} |
Burda yapılan şey, öncelikle UpdateData işlevi ile gönderilecek metnin kontrolden,
metin isimli değişkene aktarılması , ardından da metni 256 bayta % karakterleri
ile tamamlanması ve Send işlevini metin ve boyutu ile çağrılmasıdır. Programımız
temel bi uygulama olduğu için göndereceği bütün paketler 256 bayttan oluşmaktadır.
Daha ileri uygulamalarda boyut, dinamik olarak belirlenmeli ve paketin boyut
bilgisi önden gönderilmelidir. Send işlevi gönderme işlemini başaramadığı
takdirde SOCKET_ERROR döndürecektir.
İstemci
uygulamamızın Bağlan düğmesine tıklayınca belirtilen IP adresine bağlanması
için yazılması gereken kod:
if(!bagli)
{
UpdateData();
soket.Create();
if(!soket.Connect(adres,port))
{
SetWindowText("İstemci - Bağlanamadı");
soket.Close();
soket.ShutDown();
}
else
{
SetWindowText("İstemci - Bağlı");
SetDlgItemText(IDC_BAGLAN,"Kop");
bagli = true;
}
} |
İstemci soketin bağlanma girişimi port ve adres bilgisini gerektir. Başarısızlık
durumunda Connect işlevi 0 döndürür. İstemciye spesifik gönderme işlevi:
UpdateData();
if(!metin.IsEmpty())
{
for(UCHAR a=0; a<256-metin.GetLength();a++ )metin+=’%’;
soket.Send(metin.GetBuffer(),metin.GetLength());
} |
Sunucu uygulamanın
gönderme işlevi, transferi kabul edilen bağlantı üzerinden yaparken, istemci
bağlantı soketini kullanmaktadır. TSoket sınıfının istemci ve sunucu için ortak
olan ve açıklanması gereken tek işlev; alma işini yapan OnReceive işlevidir:
alinan->GetWindowText(buf);
char *tampon=new char[256];
UINT okunan = Receive(tampon,256);
tampon[okunan]=0;
CString str;
str.Format("%sMuhatabım:\r\n %s",buf,tampon);
str.Remove(’%’);
str+="\r\n";
alinan->SetWindowText(str);
CSocket::OnReceive(nErrorCode); |
Öncelikle
aldığımız mesajları alınan kutusunda görüntülemek için, alinanlaraAt işleviyle
daha önceden adresi bildirilen alinan kontrolünün içeriğini Başlık kısmında
üye değişken olarak tanımlanmış buf isimli değişkene atmalıyız. bunu GetWindowText
işlevi yapmaktadır. Daha sonra alınan paketleri içine atmak için, tasarım gereği
256 baytlık olan bir karakter dizisi tanımladık. Receive işlevi, parametre olarak
bu tampon belleğin adresini ve kaç karakter okunacağını verip çağrıldığında,
alınan bayt sayısını döndürür. Alinan bayt sayisini alinan isimli değişkene
atmamızın nedeni ise tampon karakter dizisinin içerdiği metnin sonuna, sonlandırıcı
karakter eklemektir. Sonraki aşamada alınan mesajları uygun bir biçimde formatlama
işlemi yapılmaktadır. Paket boyunu 256’ya tamamlamak için eklenmiş olan % karakterlerini
alınan mesajdan attıktan sonra, mesajın son halini SetWindowText işlevi ile
alinan isimli kontrole atarak paket alma işlemini tamamlamış oluyoruz.
Çok temel bir haberleşme uygulaması yapmış olduk. İleri düzey bir sohbet yazılımı
isterseniz, çoklu kullanıcı desteği ve ekonomik bir paket yönetimi için kolları
sıvamalısınız. İyi çalışmalar..
Visual C++.NET Proje Kodlarını indirmek
için tıklayınız.
Makale:
Temel Bir Sohbet Yazılımı C++ ve C++.NET dili Talha Orak
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|