C#.Net Network Programcılığı
Network ortamında işlemler portlar kullanarak gerçekleştirilmektedir.Bu yüzden port dinlemek ,porta veri yollamak ve ya da porta gelen verinin okunabilmesi için C#’ın içinde bir çok class tanımlanmıştır.
Network porgramcılığı yaparken C#’ta Kullanılan Yardımcı Kütüphaneler:
Aşağıdaki class’lar network uygulamalarında kullanılan kütüphanelerdir.
using System.Net.Sockets //Socket İşlemleri
using System.Text //Tip Çevirme İşlemleri
using System.Net.IO//Dosyalama İşlemleri
using System.Net.Threading//Kanal İşlemleri
using System.IO //Giriş-Çıkış İşlemleri

using System.Net.Sockets Kütüphanesi:
Bu kütüphane sayesinde porta veri yollamak,portu dinlemek, portan veri okumak gibi işlemleri rahatlıkla gerçekleştirilebilir.
Aşağıda bu kütüphaneye ait olan class’lar ve işlemlerinden bahsediliyor.
1. TcpListener:
Bu class’ta türeteceğimiz yavru üye sayesinde bilgisayarda numarasını belirteceğimiz port sürekli dinlemeye alınır.Bir client makinenin server’a bağlanabilmesi için bağlanılan portun server tarafından dinleniyor olması gerekir.
• TcpListener1.Start():Bu method sayesinde verilen port numarası dinlemye alınır.Server
ve client’ın iletişime geçmesi için aynı port numarasını kullanıyor olamaları gerekir.
• TcpListener1.AcceptSocket():Bu method sayesindeserver’a bağlanan client’ları kabul edebiliriz ya da rededebiliriz.
• TcpListener1.AcceptTcpClient():Bu methodla da bağlanan kullanıcıların bağlantı isteklerini kabul ya da rededebiliriz.
• TcpListener1.Stop():Dinlemeye alınmış portun dinleme işlemi iptal edilir.
• TcpListener1.LocalEndPoint:Bu bir method değil bir özelliktir.Bu method sayesinde sever’a bağlanan client’ların IP numaralarını öğrenebiliriz.
2 TcpClient:
Network oratmında mesaj ve ya komut göndermek için kullanılan bir class’tır.Bu nesne sayesinde server makinesine bağlanılabilir.Bağlantı işlemi için server makinesinin IP numarasına ve TcpListener class’ının dinlediği portun numarasına ihtiyaç vardır.
• tcpClient.Connect():Belirtilen makineye yine belirtilen porttan bağlanmayı sağlayan bir methoddur.
• tcpClient.GetStream():Bu method NetworkStream class’ına ait yavru üyeye aktarılarak porttan veri okuyabilir.ve ya porta veri gönderebilir.
• tcpClient.ReceiveBufferSize:Portan veri okuma boyutunu belirleyen özelliğidir.
• tcpClient.SendBufferSize: Porta gönderilen veri boyutunu belirleyen özelliğidir.
• tcpClient.Close:Bağlantıyı kapatan method’dur.
3 NetworkStream:
Bu class sayesinde makineler arası bğlantı oluşturularak verilerin istenilen adrese gönderilmesi sağlanabilir.TcpClient veya Socket nesnesini kullanark makineler arası bağlantı kurulan porta gelen ve yine aynı porta gönderilen tüm veriler bu class’ın üyesi olan yavru değişken sayesinde gerçekleştirilebilir.
• networkStream.Read(dizidegisken,ilk eleman,kaceleman):Porttan bilgi okumka için kullanılan methottur.
• networkStream.Read(dizidegisken,ilk eleman,kaceleman): TcpClient veya Socket nesnesiyle beraber makineler arasında oluşturulan akış’a veri yazdırmak için kullanılan methottur.
• networkStream.CanRead:Bu özellikle de porttaki verinin okumaya müsait olup olmadığını öğrenebiliriz.
• networkStream.CanWrite:Bu özellikle de porta veri gönderme modunun aktif olup olmadığını öğrenebiliriz.
• networkStream.DataAvailable:Bu özellikle de oluşturulan akışta bilgi gidip gitmediği öğenilebilir.
• networkStream.Length:Akışta bulunan verinin boyutunu bu özellikle öğrenebiliriz.

4 Socket:
4.1 Port ve Soket Kavramları
Host cihazındaki bir TCP üst-katman kullanıcısı bir port numarası ile tanımlanır. Port değeri IP internet adresi ile birleşerek bir soket oluşturur. Bu değer internet boyunca tek olmalıdır. Bir soket çifti her bir uç-nokta bağlantısını tek olarak tanımlar.
Örneğin;
Gönderici Soket = Kaynak IP Adresi + Kaynak Port Numarası
Alıcı soket = Hedef IP Adresi + Hedef Port Numarası
Bir bilgisayarda birden çok soket bulunabilir. Örneğin aynı anda hem telnet socketi hem de ftp soketi açık olabilmektedir. Socketleri birbirinden ayırmak ve istemci-sunucu ikilisini birbiri ile buluşturmak için her soket programın PORT numarası vardır. Örneğin FTP'nin port numarası 21'dir. Bir FTP istemci,FTPsunucunun 21. portta çalıştığını bildiğinden direkt onunla temasa geçer. Telnet 23.'u portta çalıştığından, telnet sunucu ile FTP sunucu karışmaz. 1-1024 arasındaki portlar standarttır ve yalnız root tarafından kullanılabilir. Eğer normal user 1024'ten küçük portları kullanmaya kalkarsa 'bind' permission hatası verir. Bu nedenle sıradan kullanıcılar soket programları için 1023'ten büyük bir port numarası seçerler.
4.2 Socket Programlama
Soketler, bir tür süreçler arası haberleşme (interprocessing) yöntemidir. Soket, soyut bir tanımla haberleşme uç noktalarıdır. Pratik olarak soketler dosyalara benzer. Soketten okumak ile dosyadan okumak arasında hiçbir fark yoktur. Sıradan bir programda dosya açmak istediğiniz zaman, çekirdeğin (kernel) sistem çağrıları kullanılarak, programınıza tam sayı bir değer verilir. Bu değer dosyanızı yönetmek için kullanacağınız dosya tanımlayıcısıdır (file descriptor). POSIX (Linux, BSD gibi UNIX benzeri) sistemlerde hemen her şey bir dosyadır. /dev dizini altında cihazlar yer alır. Her cihaz için major ve minor numarası ile tanımlanan özel dosyalar bulunur. Bunlar Block Device ve Character Device diye iki kısma sınıflandırılmıştır. Terminaliniz, konsolonuz, FIFO ve pipe gibi veri yapıları; hepsi kullanıcı için birer dosyadır. Bu nedenle soketlere dosya gözüyle bakabilir ve yazmak için write(), okumak için ise read() gibi dosya fonksiyonlarını kullanabilirsiniz. Ancak sokete özel fonksiyonları kullanmak daha kullanışlı olacaktır.
Aklınıza gelebilecek hemen her internet programı socket program olarak çalışır. Örneğin web sunucuları 80, telnet sunucuları 23 numaralı port üzerinde çalışan soket programlardır.
Soket programlamaya özel bazı terimler:

İstemci (Client):
Hizmet isteyen soket programlara denir. İstediği zaman sunucuya (server) bağlanır, görev verir ve sonuçları alıp bağlantıyı koparır.

Sunucu (Server):
Hizmet veren soket programdır. İstemci herhangi bir anda kendisine bağlanıp, ondan hizmet isteyebileceğinden sürekli çalışmak zorundadır.

Çeşitli soket türleri vardır. Bunlardan en yaygın olarak kullanılanı "Stream Soketler" dir.
Programda socket() açarken türü belirtilir. Stream soketlere bağlantı yönelimli (connection oriented) soketler, Datagram soketlere ise bağlantısız (connectionless) soketler denir.

Stream soketler, TCP/IP protokolünün taşıma katmanında bulunan TCP'yi (Transmission Control Protocol) kullanır.
1. Stream soketler verileri sıralı gönderir, datagram soketleri sıralı göndermeyebilir.
2. Stream soketler veri bütünlüğünü garanti eder , Datagram soketler veri bütünlüğünü garanti etmez. (TCP bir paketi gönderdiği zaman, karşı taraf paketi aldığını haber vermeden, kendini o paketi göndermiş saymaz ve tekrar gönderir. Ayrıca paketin doğru gidip gitmediğini anlamak için başlık bilgisinde checksum kontrol bilgisi tutar. UDP'de checksum kontrol bilgisi tutar ancak checksum yanlışsa aynı paketi tekrar istemez.)
3. Stream soketler, işlem bitene kadar kesintisiz bir bağlantı kurar. Datagram soketler ise bağlantı kurmaz. Sadece veri göndereceği zaman bağlantı kurar ve işi bitince bağlantıyı koparır.
İnternet ( yada intranet ) ortamında bilgi transferi ve bağlantı işlemleri için kullanılan en önemli class’tır.İnternet’te tüm işlemler Socket’ler vasıtasıyla gerçekleştirilmaktedir.
TcpClient Socket nesnesinden türetilmiş ve TCP/IP protokolu kullanarak bağlantı sağlayan bir class’tır.Socket ise diğer protokollere de destek vermektedir.
4.3 Socket Yaratmak:
Socket yeni=new Socket(AddressFamily.InterNetWork,SocketType.Stream,Protocoltype.Tcp);
Bu kodda yazılanları açıklayalım;
AddressFamily.InterNetWork:Socket’in NetWork Adres bilgisidir.
SocketType.Stream:Socket’in tipini belirleyen özelliğidir.Burada makineler arası bilgi alışverişi için kullanılacağı belirtildi.
Protocoltype.Tcp:İşlemlerinde kullanacağı protokolu belirleyebiliriz.
• socket1.Connect(“IP numarası”,portno);Beliritlen ıp numaralı bilgisayara belirtilen port numarasından bağlanmak için kullanılan bir methottur.
• socket1.Accept():Gelen bağlanti isteklerini kabul etmek için kullanılan bir methottur.
• socket1.Close():Socket’i kapatan bir methottur.
• socket1.Receive(gelen,gelen.Length,0): Porttan veri okumak için kullanılan bir methottur.
• socket1.Send(yolla,yolla.Length,0):Bu methodla da porta veri gönderebiliriz.
• socket1.Connected():Socket bağlantısının aktif olup olmadığını bu özellikle öğrenebiliriz.
• socket1.Shutdown():Bu methodle veri okumayı,veri göndermeyi ya da her ikisini birden kapatabiliriz.
• socket1.listen(n):Belirtilen bağlantı sayısı kadar makineyi dinlemeye alır.
• Socket1.LocalEndPoint:Bağlantı kurduğumuz makinenin IP numarasını ve portunu bu yolla öğrenebiliriz.
Using System.Text Kütüphanesi:
Bu kütüphane aslında network uygulamaları için konulmuş değildir.Fakat Socket uygulamalarında porttan veri göndermek ve porttan veri okuyabilmek için String’den Byte dizisine ve ya Byte dizisinden String’ dönüşüm yapmamız gerekmektedir.Bu dönüşümler ise “System.Text” kütüphanesi içinde tanımlanmış üyeler tarafından gerçekleştirilmektedir.(Gönderilen veri string formatındadır,ancak iletim yapılabilmesi için byte’a çevrimi gerekmektedir.)
• Encoding.ASCII.GetBytes(degisken.ToCharArray()):
Encoding.ASCII.GetByte() methoduyla string değişken değerini Byte dizisine aktarabiliriz.
• Encoding.ASCII.GetString(bytedegisken): Bu methodla da porta gelen ve paremetre ile girilen Byte dizi değişken değeri stringe çevrilerek işlemlerde kullanılabilir.


Using System.Thread Kütüphanesi:
C# çok kanallı programlamayı (multi threading programming) standart olarak destekler.Çok kanallı bir program paralel zamanlı çalışabilen iki yada daha fazla parçayı içerir.Bu tür bir programın her parçasına thread denir ve her kanal farklı bir çalışma yolu tanımlar.Böylece ; çok kanallılık ,çok görevliliğin(multitasking) özelleştirmiş bir şeklidir.
Çok kanallı programlama ,C# dili ne .NET Framework içindeki sınıflar tarafından tanımlanan özelliklerin bir kombinasyonuna dayanır.
Bu kütüphane network ortamıyla ilgili gözükmese de network programlarında en çok kullanılan kkütüphanelerden biridirÇünkü yapacağımız işlemleri sonsuz bir döngü içerisnde yapmalıyız(sürekli aynı portu dinlemek vs. gibi işlemler).Sonsuz döngi olarak da for(;;) döngüsünden bahsediyoruz.Bu durumda uygulamamız başka hiçbir işlem yapamayacak .
Örnek vermek gerekirse TcpListener objesi herhengi bir portu dinlemeye aldığında uygulamamızla ilgili başka hiçbir işlem gerçekleştiremeyiz.Bu yüzden port dinleme işlemleri için ayrı bir kanal oluşturup ,bu kanal yardımıyla port işlemlerini halletmeli,diğer kanal( yada kanalllarla ) da diğer işlemleri yapmalıyız.
Uygulamamızda birden fazla kanal oluşturabilir, bu kanallarla ilgili öncelik tanımı yapabiliriz.
• Kanal.Priority:Bu özellikle bağlanan kullanıcının performansını belirleyebiliriz.(Önce bağlansın veya geç bağlansın vs.)
Projemde veri tabanı olarak SQL Server 2000 kullanacağımı belitmiştim.Sql Server 2000 ile ilgili genel özellikler aşağıda anlatılmaktadır.
Using System.IO Kütüphanesi:
Bu kütüphane de network işlemleriyle çok alakalı gözükmese de IM servis’i tasarlamak istediğimiz zaman aynı zamanda kullanıcıların kendi aralarında dosya transferi yapmasına olnak sağlayan bir özelliği de sunmamız gerekmektedir.Bu işlemleri yaparken de “using System.IO” kütüphanesinden yararlanacağız.

Kısaca bu kütüphenenin özelliklerinden bahsedelim.
C# I/O işlemlerini akışlar aracılığıyla destekler.Bir akış,C# I/O sistemi tarafından bir fiziksel aygıta bağlanır.Tüm akışlar bağlı oldukları cihazlar bazı farklı özellikler gösterse bile aynı şekilde davranmalıdırlar.
• StreamWriter:
Karakter tabanlı bir çıktı akışı oluşturmak için bir Stream nesnesini bir StreamWriter içine yerleştirmek yeterlidir.
• StreamReader:
Karakter tabanlı bir girdi akışı oluşturmak için bir Stream nesnesini bir Stream Reader içine
yerleştirmek yeterlidir.


KAYNAKLAR

1. Herkes İçin C# (HERBERT SCHILDT Alfa Yayınları)
2. Zirvedeki Beyinler-10 (NİHAT DEMİRLİ-YÜKSEL İNAN Prestige Yayınları)
3. www.wikipedia.com
4. www.uludag.org.tr

Gönderen: Nurhan Öztermeli