C# LAN üzerinde TCP Bağlantısı ile Veri Aktarımı (Konsol)

Ağ bağlantısı kullanmak üzere geliştirdiğimiz uygulamalarda, ağ üzerinde bulunan diğer bilgisayarlarla veri aktarımı yapabilmek önemli bir konudur. .Net Framework bu işlemleri kolaylıkla yapabilmemizi sağlayan çok güçlü bir altyapıya sahiptir. C# programlama dilini kullanarak yaptığımız programları, farklı bilgisayarlarda çalışıyor olsalar bile kolaylıkla iletişim kurdurabiliriz.



Ağ üzerinde veri aktarımı gerçekleştirmek istediğimizde karşımıza temelde iki önemli protokol gelmektedir UDP ve TCP... Bu yazıdaki örneğimizde verinin iletildiğinden emin olmak için, karşı tarafla el sıkışmalı bağlantı prensibine dayanan TCP protokolünü kullanan bir programı nasıl geliştirebileceğimize bakacağız.

TCP, karşı taraftaki programla öncelikle bağlantı kurulması ve ardından veri aktarımına başlanması prensibiyle çalışır. Gönderilen her mesajın karşı tarafa sağlıklı bir şekilde iletildiğinden ve paketlerin doğru sırayla gönderildiğinden emin olur (Flow Control). Veri gönderilirken oluşabilecek bozulmalarda da protokol veriyi otomatik olarak yeniden göndererek sorunu kendisi çözer. Üstelik bütün bunların gerçekleşmesi için yapmanız gereken herhangi bir şey yok. Her şey otomatik olarak yapılıyor.


Başlayalım


Öncelikle sistemi açıklamak istiyorum. İki adet C# Console Application yaratarak birini verinin gönderilmesi diğerinide gönderilen verinin alınmasını (dinlenmesi) sağlayacak şekilde programlayacağız. Bu programlar aynı ağa bağlı farklı bilgisayarlarda bulunacak. Aktarım işlemi yerel ağ bağlantısı üzerinden gerçekleştirilecek.

Bu örnekte programlar birbirlerini otomatik olarak bulmuyor. Diğer bilgisayarın IP adresini, gönderici programa elle belirtmeniz gerekecek.

(Programlardan bir tanesini köprü bağlantısı ile konfigüre edilmiş sanal makinede çalıştırabilirsiniz)

Gönderici Program


Visual Studio'yu çalıştırarak, bir Console Application yaratın.

Şimdi soketleri ve TCP sınıflarını kullanabilmek için aşağıdaki kütüphaneleri ekleyin.

using System.Net;
using System.Net.Sockets;

Sonrasında bağlantıyı yaratmak ve kullanmak üzere depolamak için bir Soket yaratıyoruz ve protokol tipi olarak TCP'yi belirtiyoruz. IP Adres ailesi için InterNetwork yani yerel ağ bağlantısı üzerinde çalışacağımızı söylüyoruz. Port olarak gönderici için ve dinleyici için 52000 seçelim.

static Socket soket = new Socket
             (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
const int PORT = 52000;

Daha sonra bağlantıyı gerçekleştirmek için aşağıdaki kodu kullanıyoruz.

soket.Connect(new IPEndPoint(IPAddress.Parse(uzakBilgisayarIP), port));

Konsol ekranına girilen metni karşı tarafa aşağıdaki gibi iletebiliriz.

string gonderilecekMesaj = Console.ReadLine();
soket.Send(Encoding.UTF8.GetBytes(gonderilecekMesaj));

Kodun Tamamı


 class Program
    {
        // TCP bağlantısını açıp tutacağımız soket:
        static Socket soket = new Socket
             (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        // Mesajı göndereceğimiz port
        // Dinleyici programın mesajları görebilmesi için
        // aynı port numarası üzerinden dinlemesi gerekir.
        const int PORT = 52000;

        static void Main(string[] args)
        {
            string uzakBilgisayarIP = "";

            Console.Title = "TCP Data Transmit - Gönderici";

            // Dinleyici programımızın çalıştığı
            // uzak bilgisayarın IP adresini isteyelim:
            Console.Write("Uzak bilgisayar IP: ");
            uzakBilgisayarIP = Console.ReadLine();

            Console.WriteLine(uzakBilgisayarIP + " adresindeki bilgisayara bağlanılıyor...");

            // Uzak bilgisayara bağlanmaya çalışalım
            try
            {
                soket.Connect(new IPEndPoint(IPAddress.Parse(uzakBilgisayarIP), PORT));
                Console.WriteLine("Başarıyla bağlanıldı!");
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("\n (X) -> Bağlanmaya çalışırken hata oluştu: " + ex.Message);
            }

            // Bağlantı sağlandığı sürece her ENTER tuşuna basıldığında
            // ekrana yazılmış olanlar diğer bilgisayara gönderilecek.
            while (true && soket.Connected)
            {
                Console.Write("Gönder: ");

                // Gönderilecek metni alıyoruz.
                string gonder = Console.ReadLine();

                // Ağ üzerinden gönderilecek her şey bytelara 
                // dönüştürülmüş olmalıdır.
                soket.Send(Encoding.UTF8.GetBytes(gonder));
            }

            Console.WriteLine("Programı sonlandırmak için ENTER tuşuna basın...");
            Console.Read();
        }
    }

Gönderici programımız hazır! Şimdi gönderilenleri karşı bilgisayardan alacak ve okunabilir hale getirecek programı yazmamız gerekiyor.



Dinleyici (Alıcı) Program


Yeni bir Console Application yaratın ve yine aşağıdaki kütüphaneleri projenize dahil edin.

using System.Net;
using System.Net.Sockets;

Gelecek Tcp bağlantısını tutarak daha sonra kullanılabilir hale getirecek Socket'imizi yaratalım.

static Socket dinleyiciSoket = new Socket
             (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Diğer bilgisayarlardan gelebilecek TCP bağlantı isteklerini dinlemek üzere TcpListener sınıfını kullanacağız. Bu sınıfı IPAddress.Any yani herhangi bir IP üzerinden ve belirlediğimiz port numarasını kullanarak gelecek istekleri kabul edecek şekilde hazırlayacağız.

TcpListener dinle = new TcpListener(IPAddress.Any, PORT);
dinle.Start();

Soketimizi dinleyici üzerinden gelecek istekleri kabul edecek hale getirelim. AcceptSocket() metodu bir bağlantı isteği gelinceye kadar bekleyecektir.

dinleyiciSoket = dinle.AcceptSocket();

Geriye sadece gelen mesajları okuyup ekrana yazdırmak kaldı.

Kodun Tamamı


    class Program
    {
        // Bağlantı isteği geldiğinde, bağlantıyı bu sokette saklayacağız
        static Socket dinleyiciSoket = new Socket
             (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        const int PORT = 52000;

        static void Main(string[] args)
        {
            Console.Title = "TCP Data Transmit - Dinleyici";

            // TCP dinleyicisini herhangi bir IPAdresinden gelebilecek
            // bağlantı tekliflerini dinleyecek şekilde ayarlıyoruz.
            // Ayrıca gönderici ile aynı PORT üzerinden dinlemesi gerekiyor.
            TcpListener dinle = new TcpListener(IPAddress.Any, PORT);
            dinle.Start();

            Console.WriteLine("Bağlantı bekleniyor...");

            // Buradan aşağısı bağlantı teklifi geldiğinde çalışacaktır.
            // Teklifi kabul ediyoruz ve dinleyiciSoketimize atayarak
            // kurulmuş TCP bağlantısına her zaman erişilebilecek hale getiriyoruz.
            dinleyiciSoket = dinle.AcceptSocket();
            Console.WriteLine("Bağlantı sağlandı. ");

            while (true)
            {
                try
                {
                    // Receive() metodu TCP bağlantısı üzerinden gelecek mesajları beklemeye ve
                    // geldiğinde okumaya yarar. Gelecek mesajı içinde saklayacağımız bir
                    // buffer yaratarak (gelenData) gelen byteları depoluyoruz.
                    // Oluşturduğumuz buffer'ın boyutu tek seferde alınabilecek byte sayısını
                    // belirlediği için, 256 byte'tan daha uzun bir data gönderildiğinde
                    // tamamını alamayacaktır. Daha uzun veriler göndermek istiyorsanız buffer 
                    // boyutunu daha büyük belirtebilirsiniz.
                    byte[] gelenData = new byte[256];
                    dinleyiciSoket.Receive(gelenData);

                    // Gelen karakterler yarrattığımız bufferın tamamını dolduramazsa (ki genelde
                    // doldurmayacaktır) kalan karakterler boşluk olarak gözükür. Bu sebeple Split()
                    // metodunu kullanarak gelen mesajın sadece metnin bittiği noktaya kadar alınmasını
                    // sağlıyoruz.
                    string mesaj = (Encoding.UTF8.GetString(gelenData)).Split('\0')[0];

                    Console.WriteLine("Gelen mesaj: " + mesaj);

                    if (mesaj.ToLower().StartsWith("exit"))
                    {
                        // Eğer mesaj 'exit' şeklinde başlıyorsa, bağlantıyı düzgün bir şekilde kapatıyoruz.
                        Console.WriteLine("Bağlantı kapatılıyor.");
                        dinleyiciSoket.Dispose();
                        break;
                    }
                }
                catch
                {
                    // Eğer gönderici program TCP bağlantısı kurulduktan sonra, düzgün bir şekilde
                    // yani exit komutu verilmeden kapatılırsa bir hata oluşacaktır. Hatayı burda
                    // ele alarak programın çökmesini engelliyoruz.
                    Console.WriteLine("Bağlantı kesildi. Çıkış yapılıyor.");
                    break;
                }
            }

            Console.WriteLine("Kapatmak için ENTER'a basın.");
            Console.Read();
        }
    }

Test Edelim


Programlarımız hazır olduğuna göre şimdi onları deneyelim. Dinleyici programınızı aynı ağda bulunan başka bir bilgisayarda (ya da sanal makinede) çalıştırın. Güvenlik duvarı sizi programın ağınızı dinlemeye çalıştığı konusunda uyarabilir. Bizim de istediğimiz bu 😊 o yüzden izin verin.

Başka bir bilgisayarda da gönderici programı çalıştırın. IP adresi istediği zaman dinleyici programınızın çalıştığı bilgisayarın IP adresini vermelisiniz. Bu adresi komut isteminde ipconfig komutunu vererek öğrenebilirsiniz. Aradığınız adres IPv4 adresi.

(Öncelikle dinleyici programın çalışması gerektiğini unutmayın.)

Sonuç

 Gönderici program:


Alıcı program



Okuduğunuz için teşekkürler. Umarım açıklayıcı olmuştur. Aklınıza takılanları sormaktan çekinmeyin!

Yorumlar



Bu blogdaki popüler yayınlar

Android Programlama: EditText Kullanarak Kullanıcıdan Girdi Almak

Bilgisayarınızın IP adresini nasıl öğrenirsiniz?

İşletim Sistemleri Türleri (Single Task, Multitask ve RTOS)

Ağ Topolojileri nelerdir? Hangi topoloji bir ağ için daha uygun?