Makale Özeti

Bu makalemde sizlerle Tcp protokolünün nasıl kullanıldığını bu protokolü kullanan bir mesajlaşma programı yazarak inceleyeceğiz. Programda clientlar sadece programın açılmasında sunucya giderek kullanıcı bilgilerinin saklanmakta olan XML dosyasını kendilerine kopyalayacak, dosyaya ulaşamadığı anda ise lokaldeki kopyasından disconnected olarak çalışabilecektir. Bunun yanı sıra clientlar kendi aralarında mesajlaşmada, online ve offline bilgilerini göndermede direkt haberleşecek ve sunucya yük bindirmeyeceklerdir.

Makale

         Merhabalar

         Bu makalemde sizlerle Tcp protokolünün nasıl kullanıldığını bu protokolü kullanan bir mesajlaşma programı yazarak inceleyeceğiz. Programda clientlar sadece programın açılmasında sunucya giderek kullanıcı bilgilerinin saklanmakta olan XML dosyasını kendilerine kopyalayacak, dosyaya ulaşamadığı anda ise lokaldeki kopyasından disconnected olarak çalışabilecektir. Bunun yanı sıra clientlar kendi aralarında mesajlaşmada, online ve offline bilgilerini göndermede direkt haberleşecek ve sunucya yük bindirmeyeceklerdir. Vede bir diğer önemli özellik ise network üzerinden gönderilen mesajların genellikle | ile ayrılarak gönderilmesine rağmen biz biraz daha farklı ve object oriented bir yaklaşımla nesnelerimizi serileştirerek network üzerinden karşı bilgisayara yollayacağız.

         İlk önce uygulamamızın ayarlarını saklayacağımız app.config dosyasını ve mesajı gönderen ve alan kişinin bilgilerinin tutulacağı Client class'ımızı yazalım.

 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
      <appSettings>
            <add key="port" value="4567"/>
            <add key="kullaniciListesi" value="\\192.168.1.100\mess\kullaniciListesi.xml"/>
      </appSettings>
</configuration>
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
 
namespace Messenger
{
    [Serializable]
    public class Client
    {
        public Client()
        {
       
        }
        public Client(string Name, string Address)
        {
            _Address = Address;
            _Name = Name;
        }
        private string _Name;
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
       
        private string _Address;
        public string Address
        {
            get { return _Address; }
            set { _Address = value; }
        }
    }
}
         Bu classta kullanıcının bilgisayarının adını ve kullanıcının ip adresini saklayacağımız değişkenler ve bu değişkenleri encapsule eden propertylerin yanı sıra bir tane Ctor bulunmaktadır, bu ctor ise bu iki değeri parametre olarak alıp ilgili değişkene atamaktadır.

         Şimdi ise Message nesnemizi inceleyelim. Bu nesnemiz göndereceğimiz mesajımızı temsil edecektir. Nesnemizdeki propertyler dışında Send isimli bir public metod mesajı göndermek için kullanılacaktır.

 
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
 
namespace Messenger
{
    public class Message
    {
        public Message()
        {
 
        }
        private string _Text;
        public string Text
        {
            get { return _Text; }
            set { _Text = value; }
        }
 
        private Client _Sender = new Client(Environment.MachineName,System.Net.Dns.GetHostAddresses(Environment.MachineName)[0].ToString());
        public Client Sender
        {
            get { return _Sender; }
            set { _Sender = value; }
        }
 
        private Client _Reciever;
        public Client Reciever
        {
            get { return _Reciever; }
            set { _Reciever = value; }
        }
 
        private MessengerBase.MessageType _Type;
        public MessengerBase.MessageType Type
        {
            get { return _Type; }
            set { _Type = value; }
        }
         Classımızın içinde yer alan proeprtylerden Text, _Text değişkenini encapsule etmektedir ve göndreceğimiz mesajın içerisinde yazılı olacak metni saklamaktadır, Sender propertysi ise biraz önce yazdığımız Client nesnesi tipindendir ve default olarak kullanıcının bilgisayar adını ve ip adresini taşımaktadır, Reciever propertysi ise mesajın gönderileceği kişi ile ilgili bilgilerin tutulacağı Client classı tipindendir, Type propertysi ise biraz sonra yazacağımız MessengerBase classımızın içinde bulunan MessageType enumeration'ı tipindendir. Bu enumeration ise Message, Login veya LogOff tplerinden olabilmektedir.

         Şimdi ise bu nesnemizi networkten yollamadan önce serialize etmemiz için gerekli metodu yazıyoruz.

 
        public string Serialize()
        {
            StreamWriter stWriter = null;
            XmlSerializer xmlSerializer;
            string buffer;
            try
            {
                xmlSerializer = new XmlSerializer(typeof(Message));
                MemoryStream memStream = new MemoryStream();
                stWriter = new StreamWriter(memStream);
                System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                xs.Add("", "");
                xmlSerializer.Serialize(stWriter, this, xs);
                buffer = Encoding.ASCII.GetString(memStream.GetBuffer());
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (stWriter != null)
                    stWriter.Close();
            }
            return buffer;
 
        }
          Serialize metodunda ise XmlSerializer nesnesinin Serialize metoduna ctoruna memorystream verdiğimiz Streamwriter nesnesini, classımızı ve XmlSerializerNamepaces tipinden bir nesneyi parametre olarak veriyoruz ve bu metod StreamWriter nesnesi aracılığıyla bilgileri memorystream nesnesine yazıyor daha sonrasında ise bize sadece bu memorystreami string e çevirmek kalıyor.
 
 
        public void DeSerialize(string xmlString)
        {
            XmlSerializer xmlSerializer;
            MemoryStream memStream = null;
            try
            {
                xmlSerializer = new XmlSerializer(this.GetType());
                byte[] bytes = new byte[xmlString.Length];
                Encoding.ASCII.GetBytes(xmlString, 0, xmlString.Length, bytes, 0);
                memStream = new MemoryStream(bytes);
                object objectFromXml = xmlSerializer.Deserialize(memStream);
                Message a = (Message)objectFromXml;
                this._Reciever = a.Reciever;
                this._Sender = a.Sender;
                this._Text = a.Text;
                this._Type = a.Type;
 
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (memStream != null)
                    memStream.Close();
            }
        }
          Mesaj kullanıcı tarafından string olarak alındığı zaman tekrardan nesneye çevirmek için kullanacağımız metod olan Deserialize metodumuzu ise yukarıdaki gibi yazıyoruz. Bunun için string olarak gelen veriyi byte dizisine çeviriyoruz ve bununbir memorystream'e aktarıyoruz daha sonra XmlSerializer ın Deserialize metodunu kullanarak bu stream i bir nesneye çeviriyoruz. Ve ilgili propertyleri mevcut classımıza atıyoruz.

         Şimdi ise bu nesneyi karşıdaki kullanıcıya göndereceğimiz Send metodunu yazalım
 
 
        public void Send()
        {
            TcpClient tcpClient = new TcpClient(_Reciever.Address.ToString(), int.Parse(System.Configuration.ConfigurationManager.AppSettings["port"]));
            NetworkStream tcpStream = tcpClient.GetStream();
            if (tcpStream.CanWrite)
            {
 
                string msg = this.Serialize();
                Byte[] inputToBeSent = System.Text.Encoding.ASCII.GetBytes(msg.ToCharArray());
                tcpStream.Write(inputToBeSent, 0, inputToBeSent.Length);
                tcpStream.Flush();
            }
        }
       
    }
}
          Send metodumuzda ise ilk önce TcpClient nesnesinin bir örneğini mesajı alacak kişinin ip adresini ve mesajın yollanacağı portu(app.config den okuyarak) vererek oluşturuyoruz ve daha sonrasında NetworkStreama oluşturduğumuz tcpclient nesnesinin getstream metodunadaki stream nesnesini atıyoruz.. Nesnemizi serileştirip bu metoddan dönen string değeri byte array'e çevirip oluşturduğumuz TcpStream in write metoduna parametre olarak veriyoruz ve bu sayede mesajımızı yollamış oluyoruz. daha sonrasında ise tcpStream nesnesinin flush metodunu çağırıyoruz.

         Makalemizin bundan sonraki kısmında ise MessengerBase isimli temel işlemlerin yazılacağı classımızı yazacağız ve mesajlaşmaların gerçekleşeceği pencereyi kodlayacağız.

oztamer@hotmail.com
tamer.oz@yazgelistir.com
oztamer@hotmail.com
 
Ornek Uygulama