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;
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
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
Yorum Gönder