|
C# ile Client/Server ve Socket programlamaya giriş |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu
makalemizde TCP protokolüyle basit bir Client/Server programı yapacağız, C# ile
socket programlama yapabilmek için System.Net.Sockets isimalanı altında bulunan
sınıfları kullanacağız. Yapacağımız programda server bir console uygulaması, client ise windows
formlarını kullanarak yapacağımız windows uygulaması olacak.Amacımız basit bir
Client/Server çatisi kurmak olduğu için uygulamamız çok basit olacaktır. Siz yazının
tamamını dikkatlice incelediğinizde ve yaratıcılığınızı kullandığınızda çok daha
gelişmiş uygulamalar yapabilirsiniz. Belki bir sunucu tabanlı script dili bile
geliştirebilirsiniz :).
şimdi yazacağımız
programda kullanıcı Windows uygulaması vasıtası ile server olan programımıza
bağlanacak. Form üzerinde bulunan butona tıkladığımızda yine form üzerinde bulunan
textbox girişindeki yazıyı server programımız alacak ve yazıda kaç karakter
olduğunu client programına gönderecek.Client program ise bir mesaj kutusu ile
kullanıcıya bildirecek.Öncelikle client olan kullanıcıdan mesajın geldiğini
düşünürek Server programımızı yazalım. Server programımızı yazmaya başlamadan
önce programda Soket programlama için kullandığımız sınıflara ve onların üye
fonksiyonlarına kullandığımız kadarıyla bir göz atalım.
::::
TcpListener Sınıfı(System.Net.Sockets) ::::
TcpListener sınıfı
TCP protokolü ile çalışan servislere bağlanmamızı sağlar. Mesela HTTP ve FTP
protokolleri TCP servislerini kullanırlar. TcpListener sınıfının kurucu fonksiyonunu
3 değişik şekilde çağırabiliriz.
1- )IPEndPoint
sınıfını kullanarak IP numarası ve port numarası içeren bir bilgiyi kullanma
yolu ile
2- )IP adresi ve port numarasını geçerek çağırma
3- )Sadece Port numarası ile çağırma.Bu durumda varsayılan ağ arayüzünüz
TCP servislerini sağlayacaktır.
Biz bu programda
3. şıktaki gibi bir kullanımı tercih ettik.
public
void Start();
TcpListener sınıfına
ait bu metod network servislerinden ilgili port'u dinleyerek verileri almaya
başlamamızı sağlar.
public
Socket AcceptSocket();
TcpListener sınıfına
ait bu metod veri transferi için geri dönüş değeri olarak bir Socket nesnesi
döndürür.Bu geri dönen socket ilgili makinanın IP adresi ve port numarası ile
kurulur.(kurucu işlev ile)
::::
Socket Sınıfı(System.Net.Sockets) ::::
Socket Sınıfı ile
ilgili aşağıdaki örneği inceleyelim
Socket s = new
Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp );
Socket sınıfının
bu kurucu işlevi parametre olarak AdressFamily dedigimiz adresleme semasi Soket
tipi ve kullanacagimiz protokol tipini alir. Bu 3 paremtere de .NET Framework
class kütüphanesinde Enum sabitleri olarak tanimlanmistir.
Programimizda yazdigimiz "Socket IstemciSoketi =
TcpDinleyicisi.AcceptSocket();" satiri ile
geri dönen soket nesnesinde bu 3 parametrede tanimlanmistir.
public
bool Connected();
Bu metod ile Soketin
baglanip baglanmadigini geri dönen bool degeri ile anliyoruz.Eger soket hedef
kaynaga bagliysa true degilse false degerine geri döner.
:::: NetworkStream Sinifi(System.Net.Sockets) ::::
NetworkStream sinifi
kurucularindan olan "void NetworkStream(Socket x);" fonksiyonu ilgili
kendisine gönderilen soket nesnesine ait datalari NetworkStream türünden nesnede
tutar.bu programda kullandigimiz soket tipi stream oldugu için bu sinifi kullaniyoruz.
NetworkStream sinifi içinde islem yapabilmemeiz için ise System.IO isiamalaninda
bulunan StreamReader ve StreamWriter siniflarini kullanacagiz.
Ön bilgileri aldığımıza
göre server programımızı yazalım. Aşağıdaki ilk kaynak kod server.cs dir. Satır
aralarına size yardımcı olabilecek yorumlar ekledim.Kaynak dosyayı özellikle
makaleme dosya olarak eklemiyorumki siz aşağıdaki kodları tek tek yazıp daha
iyi öğrenin.
::::
TcpClient Sinifi(System.Net.Sockets) ::::
Tcp servislerine
bağlantı sağlamak için TcPClient sınıfı kullanılır. Istemci programımızda TcpClient
sınıfının kurucu işlevini kullanıyoruz.
İlk parametre bilgisayar adı ikincisi ise port numarasıdır.
public NetworkStream GetStream();
Bu metod ile belirtilen
port tan gelen veriler bir NetworkStream nesnesine aktarılır. GetStream metodunun
geri dönüş değeri NetworkStream olduğu için atama işlemini NetworkStream türünden
bir nesneye yapmamız gerekir.
Not: Yeşil ile yazılan satırlar yorum satırlarıdır.Html formatında bir alt satıra
inmiş olan yorum satırlarını copy&paste ile programınıza aktarırken o satırları
tekrar tek satır haline getirmeyi unutmayın, aksi halde programınız derlenemez.
//Server.cs
using
System; // bunu her zaman eklememiz lazim
using System.IO ; //StreamReader ve StreamWriter siniflari
için
using System.Net.Sockets; // Socket, TcpListener ve NetworkStrem
siniflari için
public
class Server
{
public static void Main()
{
//Bilgi alisverisi için
bilgi almak istedigimiz port numarasini TcpListener sinifi ile gerçeklestiriyoruz
TcpListener TcpDinleyicisi =
new TcpListener(1234);
TcpDinleyicisi.Start();
Console.WriteLine("Sunucu baslatildi...")
;
//Soket baglantimizi yapiyoruz.Bunu
TcpListener sinifinin AcceptSocket metodu ile yaptigimiza dikkat edin Socket IstemciSoketi =
TcpDinleyicisi.AcceptSocket();
// Baglantının olup olmadığını
kontrol ediyoruz
if (!IstemciSoketi.Connected)
{
Console.WriteLine("Sunucu
baslatilamiyor...") ;
}
else
{
//Sonsuz
döngü sayesinde AgAkimini sürekli okuyoruz
while(true)
{
Console.WriteLine("Istemci
baglantisi saglandi...");
//IstemciSoketi
verilerini NetworkStream sinifi türünden nesneye aktariyoruz.
NetworkStream AgAkimi
= new NetworkStream(IstemciSoketi);
//Soketteki
bilgilerle islem yapabilmek için StreamReader ve StreamWriter siniflarini kullaniyoruz
StreamWriter AkimYazici
= new StreamWriter(AgAkimi);
StreamReader AkimOkuyucu
= new StreamReader(AgAkimi);
//StreamReader
ile String veri tipine aktarma islemi önceden bir hata olursa bunu handle etmek
gerek
try
{
string
IstemciString = AkimOkuyucu.ReadLine();
Console.WriteLine("Gelen
Bilgi:" + IstemciString);
//Istemciden
gelen bilginin uzunlugu hesaplaniyor
int
uzunluk = IstemciString.Length;
//AgAkimina,
AkimYazını ile IstemciString inin uzunluğunu yazıyoruz
AkimYazici.WriteLine(uzunluk.ToString());
AkimYazici.Flush()
;
}
catch
{
Console.WriteLine("Sunucu
kapatiliyor...");
return
;
}
}
}
IstemciSoketi.Close();
Console.WriteLine("Sunucu Kapatiliyor...");
}
}
İşte buda Istemci
programımız. Öncelikle şunu belirtiyimki aşağıdaki kodların çoğunu Visual C#
kendiliğinden hazırladı, o yüzden size Tavsiyem Visual C# kullanmanız. Öncelikle
aşağıdaki şekilde gördüğünüz form yapısını benzer bir form hazırlayın.Sonra
da buton_click metodunu form_kapatma metodunu ve using ifadelerini ekleyin.
Yada zamanınız çoksa aşağıdaki kodları teker teker yazın. (İsteyene kaynak kodu
da gönderebilirim)
//client.cs
using
System;
using System.Net.Sockets;
using System.IO ;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
public
class Form1 : System.Windows.Forms.Form
{
//Burda server da tanımladıklarımızdan farklı olarak TcpClient
sınıfı ile serverdan gelen bilgileri alıyoruz
public TcpClient Istemci;
private NetworkStream AgAkimi;
private StreamReader AkimOkuyucu;
private StreamWriter AkimYazici;
private System.Windows.Forms.Button buton;
private System.Windows.Forms.TextBox textbox;
private System.ComponentModel.Container components =
null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
//Bu satırları Visual C# oluşturdu.
this.buton = new System.Windows.Forms.Button();
this.textbox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
this.buton.Location = new System.Drawing.Point(8, 40);
this.buton.Name = "buton";
this.buton.Size = new System.Drawing.Size(248, 23);
this.buton.TabIndex = 0;
this.buton.Text = "Sunucuya Baglan";
this.buton.Click += new System.EventHandler(this.buton_Click);
this.textbox.Location = new System.Drawing.Point(8, 8);
this.textbox.Name = "textbox";
this.textbox.Size = new System.Drawing.Size(248, 20);
this.textbox.TabIndex = 1;
this.textbox.Text = "Buraya Sunucuya göndereceginiz yaziyi yazin";
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(264, 69);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.textbox,
this.buton});
this.MaximizeBox =
false;
this.Name = "Form1";
this.Text = "C#nedir?com";
this.Closing += new System.ComponentModel.CancelEventHandler(this.form1_kapatma);
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
//giriş noktamız olan mainde yeni bir form1 nesnesini
çalıştırıyoruz
static void Main()
{
Application.Run(new Form1());
}
//From1 yüklendiğinde TcpClient nesnesi oluşturup AgAkımından(NetworkStream)
verileri okuyoruz
private
void Form1_Load(object sender, System.EventArgs e)
{
try
{ Istemci =
new TcpClient("localhost",
1234);
}
catch
{
Console.WriteLine("Baglanamadi");
return;
}
//Server programında yaptıklarımızı burda da yapıyoruz. AgAkimi =
Istemci.GetStream();
AkimOkuyucu = new StreamReader(AgAkimi);
AkimYazici = new StreamWriter(AgAkimi);
}
}
private void buton_Click(object sender, System.EventArgs e)
{
//Kullanıcı
butona her tıkladığında textbox'ta yazı yoksa uyarı veriyoruz
//Sonra
AkimYazici vasıtası ile AgAkımına veriyi gönderip sunucudan gelen
//cevabı
AkimOkuyucu ile alıp Mesaj la kullanıcıya gösteriyoruz
//Tabi
olası hatalara karşı, Sunucuya bağlanmada hata oluştu mesajı veriyoruz.
try
{
if (textbox.Text=="")
{
MessageBox.Show("Lütfen
bir yazi giriniz","Uyari");
textbox.Focus();
return ;
}
string yazi;
AkimYazici.WriteLine(textbox.Text);
AkimYazici.Flush(); yazi =
AkimOkuyucu.ReadLine();
MessageBox.Show(yazi,"Sunucudan
Mesaj var");
}
catch
{
MessageBox.Show("Sunucuya baglanmada
hata oldu...");
}
}
//TVe
bütün oluşturduğumuz nesneleri form kapatıldığında kapatıyoruz.
public void form1_kapatma(object o , CancelEventArgs ec)
{
try
{
AkimYazici.Close();
AkimOkuyucu.Close();
AgAkimi.Close();
}
catch
{
MessageBox.Show("Düzgün kapatilamiyor");
}
}
Aşağıdaki
server ve client programlarımızın aynı anda çalıştıkları sırada alınmış ekran
görüntüleri mevcuttur.
Yazı hakkında sorularınızı bana sorabilirsiniz. Kaynak kodları özel bir istek
geldiğinde buraya koyabilirim.
Makale:
C# ile Client/Server ve Socket programlamaya giriş C#, Visual C# ve .NET Sefer Algan
|
|
|
-
-
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
|
|