Ana içeriğe atla

Python Soket Programlama

Merhaba arkadaşlar. Bugün sizlerle birlikte Python'da socket programlama yapacağız.
Bunun için Python da socket kütüphanesini kullanacağız. Peki nedir bu socket programlama?

Soket programlama, sizin iki program arası yada iki bilgisayar arası iletişim kurmanızı sağlar. İşte bizde bugün iki programımızı birbiri ile haberleştireceğiz. Bunun için elimizde iki program olacak. Birinci program,mesaj bekleyen program olacak, diğeri ise mesaj gönderen program.
Tüm kodları tek tek açıklayarak sizi sıkmak istemiyorum . Kodu yazıyorum ve içine gerekli açıklamayı koyuyorum. Siz bakarak birşeyler anlarsanız, bu size daha faydalı olur.

Mesaj bekleyen program(server.py)


Mesaj gönderen program(client.py)

 

Şimdi ilk olarak server.py dosyasını çalıştıralım. Çıktı şöyle olmalı



Daha sonra client.py dosyasını çalıştırdığımız zaman, son durumlar şöyle olacak

server.py


client.py


Gördüğünüz gibi Python ile socket programlama yapmak oldukça kolay. Socket programlama ile yapabilecekleriniz tamamen sizin hayal gücünüzle sınırlı. Görüşmek üzere...

Yorumlar

  1. Bağlantı yapıldı
    Traceback (most recent call last):
    File "C:\Users\casper\Desktop\client.py", line 9, in
    client.send("Mesaj: Coderistan was here!") # mesaj gönderiyoruz
    TypeError: a bytes-like object is required, not 'str'

    Bu hatayı aldım.

    YanıtlaSil
    Yanıtlar
    1. Merhaba. Sanırım Python3 kullanıyorsunuz. Python3 üzerinde veri gönderimi byte olarak yapılmalı. O yüzden ilgili satırı şu şekilde değiştirmeniz yeterli olacaktır sanırım.

      client.send("Mesaj: Coderistan Was Here!".encode())

      Sil
    2. Cevap için çok teşekkür ederim. Bu socket örneklerinin devamı gelicek mi?

      Sil
    3. Rica ederim. Bu aralar yoğun olduğum için devam edebileceğimi sanmıyorum. Ancak sorularınız varsa benimle iletişim kurabilirsiniz, elimden geldiği kadar yardımcı olmaya çalışırım.

      https://coderistan.blogspot.com/p/iletisim.html
      https://t.me/coderistan

      İyi çalışmalar :)

      Sil
    4. Şimdide bu hatayı veriyor.

      server.py
      server.bind((host,port)) # bağlantıyı kuruyoruz
      OSError: [WinError 10048] Normal olarak her yuva adresi (iletişim kuralı/ağ adresi/bağlantı noktası) için yalnızca bir kullanıma izin veriliyor

      Sil
    5. Bu hata program ile alakalı değildir. Eğer önceden bağlantıyı olağan dışı sonlandırdıysanız port açık durumda kalmış olabilir. Bu yüzden yeni bir port numarası seçerek tekrar denemeniz gerekir.

      Ya da socket ayarlarını değiştirerek portun yeniden kullanılmasını sağlayabilirsiniz

      server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

      Sil
    6. port numarasını değiştirdim oldu. Tekrardan teşekkürler. :)

      Sil
    7. Rica ederim kolay gelsin

      Sil
  2. Merhaba, ben iki bilgisayarımda deneme yaptım. Öncelikle ilk bilgisayarıma server.py dosyasını oluşturdum. ikincisinde client.py dosyasını oluşturdum,
    (bu arada iki bilgisayarda telefondaki internete baglı:)) host yazan yerede cmd den ipconfig yazıp çıkan IPv4 Address kısmındaki ip numarasını yazdım. server.py sonra client.py dosyasını çalıştırdım ve baglantı oldu. Ama baglantı kısmı aynı ip baglı oldugu için çalıştı ama ben bunu aynı internete baglı olmadan server ile veri alışverişi yapmak istiyorum, nasıl yapabilirim? birde bu port tam olarak ne işe yarıyor? bir kere kullandıgım portu bir daha kullanınca hata veriyor.

    YanıtlaSil
    Yanıtlar
    1. Merhaba. Öncelikle aynı internete bağlı olmadan alışveriş yapmak istiyorum derken sanırım herhangi bir yerden bağlantı kurabilmek istiyorum demek istediniz. Bunun için ngrok kullanarak bilgisayarınızdaki bir port numarasını dışarı açıp, ngrok yardımıyla domain+port kullanarak bağlanabilirsiniz.

      Port denilen şeyi kapı olarak düşünebilirsiniz. Bir ev düşünün, girmek için birçok kapısı olabilir. İşte port numaraları da her bağlantı için ayrılabilen, kullanılabilen kapılardır. Bir portu tekrar kullanamama sebebi, yukarıda bir yerde yazmıştım. Programı ani olarak kapatırsanız port açık kalır, sanki birisi o portu kullanıyormuş gibi durur ve işletim sistemi o portu size kullanmanız için vermez. Böyle bir durumla karşılaşmamak için kodlarınızda server'inizin ayarını şu şekilde yapın

      server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

      Sil
    2. Denedim ama client.py dosyasını çalıştırınca "hedef makine etkin olarak reddettiğinden bağlantı kurulamadı" yazdı. Nasıl çalıştırılacağını kod üzerinden gösterebilir misiniz? birde port açınca 8 saatlik kullanım süresi veriyor. Ama ben bilgisayarım açık kaldığı sürece bağlantı kabul etsin istiyorum.

      Sil
    3. ngrok ile kullandıysanız, saat sınırını kaldırmak için aşağıdaki sayfadan yardım alabilirsiniz. Kişisel bilgisayarınızın uzun süre açık kalması fikri doğru değil, sunucu almanız daha doğru. Tabii illegal birşey yapıyorsanız bilemem, o konuda yardımcı olamam.

      https://stackoverflow.com/questions/51121901/ngrok-session-expired-raspberry-project

      ngrok ile açacağınız port http,https değil tcp olmalı. yani

      ./ngrok tcp PORT_NO

      Bu şekilde deneyip, bana verilen bilgileri kullanarak bağlantı yaptığımda başarılı oldum. Olmuyorsa da, güvenlik duvarınız ile ilgili bir problem olabilir. Dediğim gibi kişisel bilgisayarlar dışarı açmak için uygun değildir, sunucu kullanmanızı tavsiye ederim.

      Sil
    4. İllegal bir şey yapmıyorum. Python socket ile ip yada porta nasıl bağlantı olur nasıl sunucuya video,fotoğraf,ses vs. gönderilir ve alınır onu anlamaya çalışıyorum. Onu yaptığım zaman projeme uyarlayıp bir sunucu kiralayıp oradan devam edeceğim. Dediğinizi yaptım güvenlik duvarını da kapattım ginede aynı hatayı veriyor ama aynı bilgisayardan bağlantıyı kabul ediyor. Bildiğiniz ücretsiz bir sunucu varsa oradan deneme yaparım.

      Sil
    5. Bağlantıyı nasıl yaptığınızı, hangi adımları uyguladığınızı yazarsanız belki daha iyi yardımcı olurum. Sunucu olarak pythonanywhere veya heroku var. Ya da üniversitede öğrenciyseniz microsoft azure size 1 yıllık öğrenci hesabı veriyor. Başka da bilgim yok malesef.

      Sil
    6. server.py dosyasındaki port kısmına 6789 yazıyorum, cmd yi açıp ngrok tcp 6789 portunu açıyorum sonra diger bilgisayardan da client.py dosyasındaki port kısmını 6789 yapıyorum. ikisinin host kısmında localhost yazıyor. Server.py sonra client.py çalıştırıyorum ama client.py de "hedef makine etkin olarak reddettiğinden bağlantı kurulamadı" yazıyor. Kabul edilen server.listen(1)

      Sil
    7. Client dosyasında port numarası yerine ngrok programının size verdiği portu kullanacaksınız. Mesela ben localhost üzerinde 8000 portunu dinliyorum, ngrok tcp 8000 yazınca bana mesela 14800 portunu ve bir domain veriyor. Bağlantıyı bu domaine size verilen port üzerinden yapacaksınız. Ayarladığınız port üzerinden değil

      Sil
    8. Biraz daha ayrıntılı anlatır mısınız? :) mesala server ve client dosyasında host kısmına ne yazılı olucak?

      Sil
    9. Server dosyasında host kısmında "0.0.0.0" yazılı ve 8000 portunu dinliyor örneğin. Bu server'in olduğu makinede dışarıdan gelen bağlantıları 8000 portuna yönlendirmek için ngrok ile geçici bir domain bağlıyoruz. ngrok tcp 8000 yazarak bize bir domain ve port vermesini bekliyoruz. Örneğin domain "abc.ngrok.io" olarak belirlendi, port ise 14800. Client dosyasının olduğu makineye gidip host kısmına "abc.ngrok.io", port kısmına da 14800 yazıyoruz. Ve artık bağlantı işleminin gerçekleşmesi gerekiyor.

      Sil
  3. Teşekkür ederim, denedim oldu. Bir sorum daha vardı :) client ile server arası sadece bir kere veri alışverişi oluyor sonra kapanıyor. Bende server da while True döngüsü kullandım client de bağlanırken 1-2 kere baglanıdıktan sonra program donuyor.

    YanıtlaSil
    Yanıtlar
    1. Rica ederim bundan sonraki sorunlar socket programlama ile alakalı değil de, sizin program yapınız ile alakalıdır diye düşünüyorum. Thread kullanmak çözüm olabilir, bir araştırın isterseniz :)

      Sil
    2. yardım için sagolun. :)

      Sil
    3. Unuttuğum bir soru vardı kusura bakmayın. Şuan kendi bilgisayarımı server olarak kullanıyorum. Server kiraladığım zaman programın bağlantı kısmında baştan aşşağı değiştirecek miyim? yoksa sadece port yerine ip mi yazıp geri kalan da aynı mı kalır?

      Sil
    4. Server kısmında değişmesi gereken birşey yok. Host ve port aynen kalır (0.0.0.0:8000 gibi). Sunucuda ngrok kullanırsanız, ngrok tarafından verilen bağlantı bilgilerini kullanırsınız aksi takdirde sunucu ip adresini alıp 8000 portuna bağlantı kurmayı denersiniz. Bu konuda kesin bir şey diyemem çünkü henüz böyle bir şey denemedim.

      Sil
  4. merhaba ben sunucunun local servera domain sorup, localin reddedip aynı domaini root servera sorduğu bir program yazmaya çalışıyorum. Yani burada iki server bir istemci olacak fakat serverların arasındaki haberleşmeyi sağlayamadım. Yardım ve fikirlerinizi bekliyorum. İyi çalışmalar

    YanıtlaSil
    Yanıtlar
    1. Merhaba. Eğer doğru anladıysam localde çalışan bir client ve server var. Client ile localdeki server'a domain soracaksınız o da reddedip root server'a(sanırım uzak sunucu) soracak.

      Şimdi neden local reddetmek üzere tasarlanacak onu anlamadım. Tam olarak ne yapmak istediğinizi detaylandırırsanız daha iyi yardımcı olabilirim. Sunucular birbiri ile direkt iletişim kuramazlar çünkü dinlemek üzere tasarlanmışlardır. Eğer sunucunun bir yere bağlantı kurması gerekecekse, tasarımın bir daha gözden geçirilmesinde fayda var çünkü bu normal bir yol değildir.

      Sil
  5. merhaba iki ayrı pc için mesajlaşmak için ne yapmalıyım

    YanıtlaSil
    Yanıtlar
    1. Merhaba. İki ayrı PC aynı ağda ise local IP adreslerini kullanabilirsiniz. Eğer aynı ağda değillerse bilgisayarlara bir statik IP bağlamalısınız. Bunu kolay yapmak için duckdns veya ngrok kullanabilirsiniz.

      Sil
  6. bu kodlara nasıl bir sunucu ekleyebiliriz yani farklı wifi ağlarına bağlı 50 60 bilgisayar olduğunu düşünün hepsi farklı şehirlerde bu ne ile yapılabilir

    YanıtlaSil
    Yanıtlar
    1. Hocam merhaba. Bu iş internet seviyesine çıktığı zaman artık socket programlamanın yeterliliği kalmaz. Çünkü artık işin içine güvenlik, ölçeklenebilirlik, yönetim ve iletişim protokolleri girer. Socket çok temel bir işlemdir. Anlatılmasının ve uygulanmasının sebeplerinden bir tanesi, iletişimin mantığını kavratmaktır.

      O yüzden artık profesyonel işlere geçildikçe, yapılan ve kullanılan ekipmanlar da profesyonel olmalı. 50-60 bilgisayar ne amaçla bağlanacak, ne iş yapacaklar gibi soruların cevabını arayarak daha doğru bir cevap verilebilir.

      Sil
  7. Merhaba ben ngrok ile farklı ağlarda çalışan bir chat programı yapmak istiyorum.Yukarıda anlatılanların hepsini uyguladım ancak bende hala aşağıdaki hatayı vermekte

    Traceback (most recent call last):
    File "C:\Users\ahmet\Desktop\ngrokclient1.py", line 4, in
    s.connect(("tcp://0.tcp.ngrok.io", 11845))
    socket.gaierror: [Errno 11004] getaddrinfo failed



    bu server dosyası:

    import socket

    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("0.0.0.0", 4443))
    s.listen(1)

    conn, addr=s.accept()
    while 1:
    msg=input(">>")
    conn.send(msg.encode())
    print("Client:"+conn.recv(1024).decode())

    buda client dosyası:
    import socket

    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("tcp://0.tcp.ngrok.io", 11845))
    while 1:
    print("Server:"+s.recv(1024).decode())
    msg=input(">>")
    s.send(msg.encode())

    Bir kaç gündür hatanın sebebini araştırıyorum henüz bir sonuca ulaşamadım.Yardımcı olursanız çok sevinirim.

    YanıtlaSil
    Yanıtlar
    1. Merhaba. Bağlantı yaptığınız adresin başındaki tcp:// ifadesini kaldırın. Yani şöyle olmalı: s.connect(("0.tcp.ngrok.io",11845))

      Sil
    2. denedim oldu zamanınızı ayırdığınız için çok teşekkür ederim.

      Sil
  8. client.connect((host,port)) # bağlantı yapılıyor
    ConnectionRefusedError: [WinError 10061] Hedef makine etkin olarak reddettiğinden bağlantı kurulamadı
    ne yapılabilir ?

    YanıtlaSil
    Yanıtlar
    1. Muhtemelen karşı makinede sunucu çalışmıyordur veya sunucu doğru ayarlanmamıştır.

      Sil
  9. Merhaba
    Client tarafında kullanıcıdan iki adet sayı istenecek, server tarafına bu iki sayı ve yapılması istenen matematiksel ifade (+,-,*,/)
    parametre olarak verilecektir. (Server’a parametre olarak yollanan ifade
    örn; 2#+#2 şeklinde olup bu ifade Server tarafında split edilerek işlemler
    yapılacaktır.)
    bu işlemi nasıl yaparım yardımcı olur musunuz

    YanıtlaSil
    Yanıtlar
    1. Merhaba. Bu işlemi yapmak basit. Sadece algoritmik olarak yardımcı olabilirim. Kodu yazması basit zaten. Öncelikle client tarafında kullanıcıdan input() ile girdi alırsınız. Daha sonra bunu socket modülünü kullanarak server tarafına gönderirsiniz.

      Server tarafında gelen mesajı Python'da bulunan string'lerin split() metodunu kullanarak parçalara ayırabilirsiniz. Sakin bir kafayla ne yapmak istediğinizi ve neye ihtiyacınız olduğunu bir kağıda yazarak ilerlerseniz yapacağınızdan eminim :)

      Sil

Yorum Gönder

Bu blogdaki popüler yayınlar

Python Subprocess

subprocess modülü, yeni bir process oluşturmayı sağlayan, bunların girdi-çıktılarını ele alma imkânı veren ve dönüş kodlarını almayı sağlayan bir modüldür. Yani daha basit bir şekilde, program içinde program çalıştırmaya imkan veren bir modüldür. Subprocess Modülünün Kullanımı subprocess basit bazı process'leri kullanmak için birkaç tane fonksiyon sunuyor. Daha karmaşık bir process çalıştırmak isterseniz, Popen sınıfını kullanabilirsiniz. Bunlara detaylı bir şekilde değinmeye çalışacağız. Şimdi basit fonksiyonları inceleyelim

Infix to postfix dönüşümü

Infix to postfix dönüşümü, operatorün ortada olduğu a+b yazım şeklini operatorün sonda olduğu ab+ yazım şekline dönüştürme işlemidir.  Infix gösterimi, bizler için kolay bir gösterim olsa da makineler için öyle değildir. İfadeyi soldan sağa doğru okurken a + b * c işleminde önce b ile c yi çarpıp sonra da a ile toplamayı kolay bir şekilde yapabiliriz çünkü bizim ifadeyi sıra ile soldan sağa adım adım giderek okuma zorunluluğumuz yok. Önce b*c nin öncelikle olduğunu görerek oradan başlar, sonra a ile kolayca toplarız.