Ana içeriğe atla

asyncore: Threading Kullanmadan Asenkron Socket Programlama

Python'da socket programlama yapabilmek için "socket" kütüphanesini kullanıyoruz. Bu kütüphaneyle bir server oluşturabilir ve gelen istekleri değerlendirerek birtakım işlemler yapabiliriz. Socket ile ilgili internette birden fazla örnek bulabilirsiniz.

Hepsi genelde bir adet server ve bir adet client içerir. Bu gayet normal, ancak bu örneklerdeki server, aynı anda iki işlem yapamaz. Yani hem başka bağlantıları dinleyip, hem de daha önceki bağlantıların kendisine gönderdiği mesajları alamaz. Ya bağlantı bekleyecektir, ya da mesaj bekleyecektir.


Hâlbuki, bir server hem bağlantı dinlemeli, hem de arkaplanda gelen mesajları dinlemeli. Bunu yapabilmek için bazı programlama çözümlerini kullanmalıyız. Bunlardan birisi threading. Aynı anda birden fazla işlem yürütme. Her yan işlem bir Thread ifade eder. Yani server'in bağlantıları dinlemesi bir Thread, mesajları dinlemesi başka bir Thread. Bu iki Thread, program boyunca aynı anda çalışabilecektir. Böylece server'imiz aynı anda iki işlem yapabilecektir.

Evet, threading ile bunu yapabiliriz, ancak başka bir yöntem arıyorsak asyncore modülü tam bize göre. Bu modülün tanımı, resmi kaynaklarda şöyle;

"This module provides the basic infrastructure for writing asynchronous socket service clients and servers."

Bu modül, asenkron socket istemcileri ve sunucuları yazmak için temel altyapıyı sağlar.

Ancak burda önemli bir noktaya dikkat çekmek istiyorum. Asyncore modülü, kesinlikle threading kullanmıyor.

Asyncore modülü, bunu işletim sisteminin yardımıyla yapıyor.  Mantık biraz karışık ve burada detayına girmeyeceğiz, ancak asyncore bu karmaşıklığı bizim için basite indirmiş ve kullanıma sunmuş. Böylece, threading kullanmadan aynı anda birden çok iş yürütmeyi sağlamış.

Konuyu fazla dağıtmadan, asyncore modülü ile nasıl asenkron bir server oluşturabileceğimiz görelim.




İlk olarak bir tane Server sınfı oluşturduk. Bu sınıfın asyncore.dispatcher sınıfını miras aldığına dikkat edin. Eğer bu sınıfı miras almazsak, Server'imiz asenkron çalışmayacaktır.

Daha sonra, __init__() içerisinde gerekli tanımlamaları yapıyoruz ve dinlemeye başlıyoruz. Tanımlamalarda socket nesnesi oluşturuyoruz, daha sonra hangi portu dinlemek istediğimizi belirtiyoruz ve en sonunda max kaç bağlantı alabileceğimizi belirliyoruz. Bu örnekte 5 bağlantı kabul ettik. Yani 5. bağlantıdan sonra artık bağlantı kabul edilmeyecektir.

Bir bağlantı geldiğinde dispatcher sınıfı, handle_accept() fonksiyonunu çağıracaktır. Biz de burada gelen bağlantıyı alıp gerekli değişkenlere aktarırız.

Mesajı da asenkron olarak dinlemek için, MsgHandler adında başka bir sınıf yazdık. Bu sınıf gelen bağlantıların gönderdikleri mesajları asenkron olarak dinler. Böylece hem server bağlantı beklemeye devam eder, hem de bağlanmış olanlar mesajlarını gönderebilirler.

MsgHandler sınıfında da, bir mesaj geldiğinde handle_read() fonksiyonu çağrılır. Böylelikle mesajımızı almış oluruz.

Son olarak, asyncore.loop() satırını yazdık. asenkron işlemlerini başlatmak için kullanıyoruz, eğer yazmazsak malesef kodumuz istediğimiz şekilde çalışmayacaktır. Bu yüzden yazmayı kesinlikle yazmayı unutmuyoruz :)

handle_ ile başlayan fonksiyonları, Java'da ki Listener'lara benzetebiliriz. Bir olay olduğu zaman çalışan bu fonksiyonları aşağıdaki asyncore dökümanında inceleyebilirsiniz.

Son olarak yukarıdaki yazdığımız server ile aynı mantıkta çalışan başka bir server'i threading yardımıyla da yapabiliriz. Ancak bu yöntem de işimize yarayabilir, farklı programlama yöntemlerini görmüş olduk :)

Hakkında yazılmış Türkçe kaynak bulunmayan başka bir modülümüzü de sizlere tanıtmış bulunuyoruz(bu yazının yazıldığı zamanlar). Bir hata,eksiklik,yanlışlık varsa, belirtmenizi önemle rica ediyorum

Sürç-i lisan ettikse affola...

Kaynak: https://docs.python.org/2/library/asyncore.html

Yorumlar

Bu blogdaki popüler yayınlar

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.

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.

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