C#nedir?com
 
YAZAR HAKKINDA
Caner Şahan
Caner Şahan
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
24 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler:  C# / VC#/.NET Caner Şahan
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : İleri
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 12.5.2004
Okunma Sayısı : 54198
Yorum Sayısı : 7     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
XML - Deniz Kılınç
emre TAŞ
yazının devamı >
emre TAŞ
Decompiling and Reverse Engineering .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Masaüstü mü ? İnternet Mi? .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
.Net Kavramları - .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Yeni Başlayanlar için - .Net Radyo
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 12.4.2021
Turhal Temizer
Mac OS/X Removing CUDA 12.4.2021
Burak Selim Şenyurt
Tie Fighter Değil, Project Tye! 12.4.2021
Burak Selim Şenyurt
Stackoverflow Sevgi Anketinde Yıllardır Bir Numara Çıkan Programlama Dili Rust Kimdir? 12.4.2021
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
C# ile Network Programlama-2
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Merhabalar, Network programlama yazı dizisinin ikincisine başlamadan önce konunun daha anlaşılır olması için birinci yazıyı okumanızı tavsiye edirim. Network’de yani haberleşmede ne nasıl oluyor bunların mantığını, nasıl çalıştığını, protocollerin nasıl ve hangi safhalarda işlediğini bilmeden network yazılımı geliştirmemiz zor olucaktır. Örneklerin kullanılabilirliği (internet çıkışları) açısından uygulamaları Tcp protocolü üzerinden geliştirmeye çalıştım. Bu protocolün internet uygulamalarında kullanıldığından bahsetmiştim. Birde OSI referans modeli ile ne yaptığımızın özüne inelim.Aşağıda meşhur OSI modelinin yapısını görebilirsiniz.

Application>>>>Şuanda bu katmanda çalışmaktayız. Network yazılımı geliştirirken bu katman bizim kullandığımız katmandır.
Presentation Application katmanının uzantıları, plug bilgilerinin tutulduğu katmandır.
Session Veri girişlerinde gelen verilerin kaydedilmesinin sağlandığı katmandır.
Transport layer Tcp-Udp protocollerininde kapsamı içinde olan katmandır. Applicationdan gelen datalar burada networkte yolculuğa çıkmak için hazırlanır.
Network Network paketler arası haberleşme olarak litaratürde geçmektedir.Ama genelde ingilizce kavramları terimsel olarak kabul etmek daha mantıklı bu yüzden frame diyeceğiz. Yani yolculuğa frameler ile başlıyoruz.Aslında network tam bir yolculuk. Düşününki bir tren yolculuğuna çıkıcaksınız. Daha önceden nereye gideceğinizi biliyorsanız, hangi trenle gideceğinizi de bilirsiniz. İşte bizim yolculuğumuzda gideceğimiz yer(destination ip), gittiğimiz yol(kablolar), başlangıç adresimiz(source ip) olarak düşünülebilir. Aslında mantık düz olarak bu. Eğerki yolda tren raydan çıkmaz, vagonları patlamaz ise hedefe ulaşabiliriz. Yolda kaza olursa bu kazalara "collision" denir. Bir kaza olduysa frameler patlar.
Data Link Bu katmanda ip header’lar ve frame trailer denilen yapılar transport layerde ayrılan framelere eklenir.
Physical Tamamen bitlerin iletildiği kablolar ve sinyallerin dolu olduğu katmandır.

Haberleşmenin Sağlanması:
Haberleşme sürekli olarak birbirine haber gönderme mantıyla çalışır. Yani bir akarsu yapısının bire bir aynısıdır diyebiliriz. Bir akarsu sürekli akar. İnsanların çok olduğu yerde akarsunun şiddeti azalır az olduğu yerde ise hızı artar. Gelelim konumuza; bizim akarsuyumuzda frameler sürekli akar. Yani sürekli akan bu akarsuda bazı bilgileri balık gibi tutmak istersek akarsuyun tamamına bir ağ koyarak bu balıkları tutabiliriz. Yani bir server uygulaması paketleri sonsuz ve bitmeyen bir döngü içinde dinleyecektir. Paketi gönderecek client’ ın ise böyle bir şeye ihtiyacı yoktur. Sonuçta client akarsuya bir kere frame bırakıyor o kadar. En az boyutlu, yani data içermeyen frame boyutu 64 byte’dır. Dolayısıyla data yüklendikçe akarsu yoğunluğu artacak ve server biraz yavaşlayacaktır.



 

.Net’te network için kullanacağımız isim alanları ve class’lar:

Kullanacağımız isim alanları System.Net, System.Net.Sockets isim alanlarıdır. Bu ikisinin tüm nesneleri networkle ilgilidir. Diğer kullanacağımız isim alanları  ise; System.Threading, System.Text isim alanları. Dilerseniz Network programımıza geçelim. Bir server ve bir client olduğunu düşünelim. Client mesaj yollayınca server bu mesajı aldığını karşı tarafada yollasın. Yani bir nevi chat. Bunun için işe server’dan başlayalım.

server.cs:

Server baştada söylediğimiz gibi sürekli dinleme durumunda olacak. Bu yüzden bu işi sonsuz bir döngü ile hallederiz ama sonsuz döngü çalışınca uygulamamızın kilitlenmesine yol açabilir. Bu yüzden sonsuz döngü olan metotu kanallamalıyız. Bu kanallamayı threading namespace’i ile yapalım. Bu kanallama işeminin uygulama başlar başlamaz olması en mantıklısı. Bu yüzden bu işlemi Formun constructor’ında gerçekleştireceğiz.

System.Threading
 
using System.Threading; public Form1()
{
    InitializeComponent();
    Thread kanal=new Thread(new ThreadStart(dinle));

    try
    {
        kanal.Start();
        kanal.Priority=ThreadPriority.Highest;
        MessageBox.Show("Server açıldı");
    }
    catch(ThreadAbortException hata)
    {
        kanal.Abort();
        MessageBox.Show("Bekleyen paket yok");
    }
}
Yeni bir kanal oluşturduktan sonra bu kanalı try-catch ile kırılmayı önlemek için kontrol etmek gerekiyor. Kanal.Priority bizim kanala verdiğimiz önceliktir. Kanal oluşturulurken, Thread class’ı ile yeni bir nesne yaratılırak dinlemeye alınıyor. Tabiki bizim dinle adlı void metotumuz sonsuz döngü........

Not:Threading işlemiyle daha önce ilgilenmeyen ve mantığını tam kavramayanlar Msdn’den yada daha önce sitede yayınlanan threading ile ilgili makalelere bakarak bilgilerini geliştirebilirler ki, geliştirmekte olduğumuz network uygulamalarının anlaşılması açısından bu kavramların iyi öğrenilmesi gereklidir..

System.Text:
 
using System.Text; // bu namespace ile text işlemlerini kolayca gerçekleştirebiliriz.Yazıyı byte dizisine,diziyi yazıya çeviren bir yapı.
byte[]dizi=Encoding.ASCII.GetBytes("CANER");//Kelimelerin ascii kodlamadaki byte değerlerine alarak diziye yerleştirir.terside geçerlidir
string veri=Encoding.ASCII.GetString(dizi);.//Aynı şekilde byte diziside string veriye çevrilebilir.

System.Net.Sockets:
Bu isim alanında bulunan bir çok class ise bizim esas işlerimizi yapan metotları barındırıyor. Bu kavramlara server’ı dinleme işlemini yapan TcpListener ile başlayalım.

TcpListener dinleyici=new TcpListener(port);
dinleyici.Start();
Yeri gelmişken port kavramını da açıklayalım. Portlar işletim sitemi, uygulamaların ve protocollerin ortak kullandıkları çıkış birimleridir. port sayısı 65000 civarındadır. 1023’e kadar olan portlar bilinen portlardır. Yani belirli protocoller için hizmet verirler. Örneğim http:(yani web) 80.porttan, ftp:21’den,telnet 23’den vs. Bunlar dünyada standart olarak kabul edilmiş numaralardır. Buradan şu çıkarki; iki bilgisayar konuşacaksa aynı port numarasını kullanmalıdır. Ben uygulamada 10000 numaralı portu bizim uygulamamız için ayırdım. Eğer bir firewall bilgisayarınızda kurulu ise bu portları kapamış olabilir. Bu yüzden firewall’dan 10000 numaralı portu açmasını ayarlayın yada firewall’u geçici olarak kapayın.

const int port=10000;
private void dinle()
{
    string cevap="Mesajiniz basariyla alinmistir.";
    string ip;
    string gelen;
    TcpListener dinleyici=new TcpListener(port);
    byte[]gelenveri_dizi=new byte[1024];
    byte[]gonderveri_dizi=Encoding.ASCII.GetBytes(cevap);
    while(true)
    {
        dinleyici.Start();
        Socket soket=dinleyici.AcceptSocket();
        soket.Receive(gelenveri_dizi,gelenveri_dizi.Length,0);
        gelen=Encoding.ASCII.GetString(gelenveri_dizi);
        listBox1.Items.Add(gelen);
        ip=soket.RemoteEndPoint.ToString();
        listBox2.Items.Add(ip);
        soket.Send(gonderveri_dizi,gonderveri_dizi.Length,0);
        label4.Text=listBox1.Items.Count.ToString();
        dinleyici.Stop();
    }
}
Görüldüğü gibi yukarıdaki örnekte sonsuz döngü ile 10000 numaralı port dinleniyor. Böylece bütün işlemler byte dizileri ile olucağı için Text kütüphanesinin metotları kullanılarak kolay biçimde dönüşüm sağlanıyor. Fakat bu dönüşümde Ascii karakterlerini kodladığımız için Türkçe karakterler doğal olarak çıkmayacak ve anlamsız karekterler oluşacaktır. İşte soket sınıfı tam anlamıyla TcpListener’ın türetildiği bir classtır ve bu class ile istenilen protocol’den soket oluşturulabiliriz. Biz burda dinlenen veriyi soket nesnesine bağlayarak soket ile networke veri yollama ve networkten veri okumayı yapabiliyoruz.TcpListener ise adındanda anlaşıldığı gibi portu dinlemeye alıyor. Burada bir dinleyip sonra porttan dinlemeyi kesiyoruz, fakat sonsuz defa bu işlemi gerçekleştirmemiz veri akışını sağlamış oluyor. Ayrıca buttonlarlada threading kanalını askıya alarak verilerin sıra ile portta yığılması ve beklemesi sağlanıyor. Resume ile bu porttan veri akışı tekrar sağlanıyor. Thread’i askıya almak bizim sonsuz döngümüzün çalışmadığı anlamına gelmez. Sadece thread’e bir ara veriyor ve veriler bir kuyruk oluşturuyor. client.cs

Gelelim client kısmına. Bu Kısımda kullanacağımız 2 tane class varki bunlar; TcpClient ve NetworkStream classları .

Tcpclient:

TcpClient  tam anlamıyla client için tasarlanmış bir yapıdır ve client’ın nereye veri göndereceği, nereye bağlanacağı, verileri nasıl paketleyeceği, nasıl ileteceğini belirlemede kullanılır.

TcpClient gonder=new TcpClient(ip,port);
NetworkStream okuryazar=gonder.GetStream();
string mesaj=textBox1.Text;
byte[]mesaj_dizi=Encoding.ASCII.GetBytes(mesaj);
byte[]gelen=new byte[gonder.ReceiveBufferSize];
gonder isimli TcpClient nesnesi oluşturularak clientımız hazır duruma geçiyor ve böylece servera baglanıyor. Daha sonra ise Tcpclient nesnesinin metodlarından olan GetStream() ile bu baglantı NetworkStream nesne’sine atanıyor. NetworkStream nesnesi ise paketleme işlemimizi yapan nesne durumundadır. Dikkat ettiyseniz gonderilen mesaj byte dizisine çevrilmiştir. Aynı şekilde gelen verilerde ReceviBufferSize özelliğinin döndüğü değer olan gelen veri boyutu kadar bir dizi yaratılıyor. Artık sadece Yazma işlemimi Okuma işlemimi yapıyoruz buna karar vermemiz gerekiyor. Bunlar ise NetworkStream sınıfının ve üyelerinin işi.

NetworkStream: NetworkStream class’ı bir stream classı’dır. Eğer daha önce dosyalama ile uğraştıysanız StreamWriter, StreamReader’ı hatırlarsanız ki mantık aynıdır. Sonuçta veri akışı bu Streamler ile yapılır.
 
if(okuryazar.CanWrite)
{
    okuryazar.Write(mesaj_dizi,0,mesaj_dizi.Length);
}
else
{
    gonder.Close();
    return;
}
if(okuryazar.CanRead)
{
    okuryazar.Read(gelen,0,(int)gonder.ReceiveBufferSize);
    string gelenveri=Encoding.ASCII.GetString(gelen);
    listBox1.Items.Add(gelenveri);
}
else
{
    gonder.Close();
    return;
}
Burada networkstream nesnesi olan okuryazar class’ından CanRead ve CanWrite ile bool bir veri tipi döner. Eğer okuma varsa karşı taraf bize veri yolluyor anlamındadır. Biz bunu okuryazar nesnesinin read metotuyla bir byte dizisi içine alarak veriyi elde ederiz. Eğer yazma durumu varsa göndereceğimiz veriyi bir byte dizi içine alarak bu diziyi okuryazar nesnesinin Write() metotu ile yazarız. Eğer bu durumlar kabul edilmezse yani bir okuma-yazma durumu permit konumu doğru değilse Stream kapanarak else bloğundan çıkılarak kaldığı yerden devam eder. Birde okumamı önce yapılacak,yoksa yazmamı yapılacak burası önemlidir. Eğer okumayı önce yaparsak ilk başta servera gelen veri olmadığı için sonsuz döngüde takılıp kalacaktır. Bu yüzden ilk önce veriyi yazalımki cevabı alalım böylece bu sorun giderilir.





Anlatımlar ile ilgili eleştirilerinizi belirtmeniz herkes için yararlı olacak ve hatalarımızı görmemize yardımcı olacaktır. C# ile Network programlama-3 yazısında görüşmek dileğiyle..

NOT : İp adresini 127.0.0.1 yapmamızın sebebi loopback ile kendi bilgisayarımız üzerinde bir network gibi çalışmamızı sağlamasıdır. Bu ip adresini değiştirerek bilinen bir ip adresinden sizin servera internet’ten mesaj gönderilmesini sağlayabilirsiniz. Bununla birlikte server’ı ilk açtığınızda bir hata alacaksınız. Bu hatanın sebebi o anda bağlanan makina olmaması ve veri gelmemesidir. Devam ederseniz, clientlar masaj yolladıkça bu hata çözülecektir. Eğer internetle işim olmaz diyorsanız TcpClient nesnesi yerine UdpClient nesnesini kullanmanızı öneririm. TcpClient ile çalışma mantığı metotları benzer.

Kaynak kodlar için tıklayın.

CANER ŞAHAN
canersahan@hotmail.com

Makale:
C# ile Network Programlama-2 C#, Visual C# ve .NET Caner Şahan
  • Yazılan Yorumlar
  • Yorum Yaz
OCA
2
2012
Mantığı Anlayabilmek Açısından Gerçekten İşe Yarıyor Eline Sağlık Dostum
TEM
9
2007
kodlarda mantık hatası var çalışmıyor...
EKİ
15
2006
CheckForIllegalCrossThreadCalls = false yapmanız yeterli olacaktır.
ŞUB
9
2006
öncelikle caner arkadaşıma teşekkür ediyorum veri paylaşımı için,, benim projemde bu sisteme mantık olarak benziyor.. tek sorunum clienlardan veri geldiğinde server onların i.p. lerini string ip=socket.RemoteEndPoint.ToString() ile ip isimli değişkene alıyorum ancak bu veriyi herhangi bir boxda yazdıramıyorum.. Cross-thread operation not valid: Control listBox1 accessed from a thread other than the thread it was created on. şeklinde hata fırlatıyor,, yardımcı olabilecek biri varsa sevinirim. Bu sorunla ilgili hem türkçe hemde diğer dillerde tam manası ile bir cevap bulamadım...
EKİ
14
2005
merhaba.ben firat.Kirgizistan-Turkiye Manas Universitesinde okuyorum.Bitirme tezi olarak bir firewall yazilimi yapmam gerekiyor.ama nerden baslayacagimi bir turlu bilemiyorum.gelen paketleri nasil ve hangi sartlar altinfakontrol edecegimi bilemiyorum.Hangi fonksiyonlari kullanmaliyim.kodlama kismi benim icin kolay fakat socket port vb. kavramlari tam olarak kavramis degilim.yazilimin fonksiyonlari neler olmali..cok zor durumdayim...bana yardim ederseniz cok sevinirim...yardim istedigim bir cok kisiden cevap gelmedi...lutfen cevabinizi bekliyorum....
EYL
21
2005
prgramın kaynak kodları indirdim fakat server ı çalıştırınca hata veriyor neden olabilir
ŞUB
11
2005
Programı çalıştıramadım zannedersem virüs programı kurulu bende ondan kaynaklı olabilir. Program gayet güzel ama tüm kontrol ler yapılmamış bende program kitleniyor. Eğer test yapılsa ve ekrana uyarı çıkarılsa idi daha güzel olurdu. Teşekkürler
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • 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