October 21, 2015

Alıntı (İbrahim):

>

Direk QString olarak niye göndermiyoruz mesajı?

Soket düzeyine indiğimizde dizgi kavramının daha altındayız. Soketler resim gibi metin olmayan bilgi de gönderebildiklerinden baytlardan oluşan bilgi gönderirler. QString'in belgesinde ise Unicode dizgi olduğu yazılı. Dizgilerin kodlanmaları (UTF-8 mi, başka bir şey mi, vs.) gibi kavramlar bu düzeyde bulunmaz.

Alıntı:

>

'Connection::sendGreetingMessage()' bu üye fonksiyon neden gerekli?

Tahmin ediyorum: Sanırım o sunucu ile istemci arasındaki bağlantı protokolünün parçası, kullanıcının gönderdiği sohbetin parçası değil. Bir anlamda, istemci sunucuya "merhaba, bağlanmak istiyorum" diyor; sunucu da ona "olur kardeş" diyor. :) İnsanların mesajları ise sendMessage() ile gönderiliyor.

Alıntı:

>

Zaten connection.cpp dosyasında yazmadık mı o üye fonksiyonu?

Connection ile Client farklı sınıf türleri; üye işlevleri farklı. Olabildiğinde tek kod yazar ve paylaştırırız ama buradaki sendMessage'lar farklı. Örneğin, birisi değer döndürüyor ama öbürü döndürmüyor. Tasarlayanlar nedense öyle düşünmüşler. :)

Alıntı:

>

bu üye fonksiyonun Türkçe karşılığı gelenBağlantı şeklinde fakat bu ne demek?

Sanırım istemci bağlandığında "şu soketten bağlantı geldi" anlamında çağrılıyor.

Alıntı:

>

Ayrıca qintptr socketDescriptor parametresine neden gerek var?

Adına bakarak "soket belirticisi". Gelen bağlantı hakkında bilgi taşıyordur.

Alıntı:

>

Umarım sorularımla sizi sıkmamışımdır.

Tabii ki değil ama ben bu örneğin soket programlanın kendisini öğrenmeye yarayacağını sanmıyorum. İşin içinde Qt ne yapıyor? Diyalog pencerelerine filan ne gerek var? :) Ben olsam soket programlamadan başka bir şey içermeyen bir örneğe bakardım:

  • Sunucu beklemeye başlasın

  • İstemci bağlansın

  • İstemci "merhaba" desin

  • Sunucu da "merhaba" desin

  • Sonlansınlar

Eğer bu kadar alt düzeyi bilmek gerekmiyorsa (ben olsam uygulamada o kadar alta inmem ve std.socket gibi üst düzey bir modülü kullanırım) o zaman üst düzey modüllere bakmak gerek.

Alıntı:

>

Malum soket programlamayı net anlatan bir kaynak bulamadım.

Daha önce yazdığım soket örneğindeki ilgisiz kodları çıkarttım. (Linux ortamında çalışıyor.) main çok basit. Geri kalanında ya Sunucu iş görüyor ya da İstemci.

Sunucu'nun kurucusu bind ve listen yapıyor. Böylece soket hazır hale geliyor. Sonra hizmetEt içinde 'accept' ile bağlantı bekliyor.

İstemci'nin kurucusu ise 'connect' ile bağlanıyor ve send ile mesaj gönderiyor. İstemci "bitti" mesajı gönderdiğinde bağlantıyı kesiyorlar.

import std.stdio;
import std.socket;
import std.getopt;
import std.string;

/* 'Unix domain socket'ler dosya sisteminde dosya olarak
* beliriyorlarmış. Anladığım kadarıyla kullanıcının bu dosyayla doğrudan bir
* işi olmuyor.
*
* Dosya isminin ilk karakterinin '\0' olması da en azından dosya isim
* çakışmalarını önlüyormuş. Hatta, böyle isimdeki dosyaların remove() ile
* silinmeleri de gerekmiyormuş.
*/
enum soketİsmi = "\0/tmp/deneme_soketi";

int main(string[] parametreler)
{
   // Sunucu rolünde mi olalım istemci mi
   enum Rol { sunucu, istemci }
   Rol rol;

   try {
       // Programın ismi dahil, iki parametre olmalı
       enforce(parametreler.length == 2);

       // Rol olamayacak değer geldiğinde hata atar
       getopt(parametreler, "rol", &rol);

   } catch {
       stderr.writefln("Kullanım:\n    %s --rol={sunucu|istemci}",
                       parametreler[0]);
       return 1;
   }

   final switch (rol) {
   case Rol.sunucu:  sunucuOl(soketİsmi); break;
   case Rol.istemci: istemciOl(soketİsmi); break;
   }

   return 0;
}

void sunucuOl(string soketİsmi)
{
   auto sunucu = Sunucu(soketİsmi);
   sunucu.hizmetEt();
}

void istemciOl(string soketİsmi)
{
   auto istemci = İstemci(soketİsmi);
   istemci.iste();
}

struct Sunucu
{
   Socket dinleyici;

   this(string soketİsmi)
   {
       // Önce bağlantıları karşılayacak olan soketi hazırlıyoruz
       dinleyici = new Socket(AddressFamily.UNIX, SocketType.STREAM);
       auto adres = new UnixAddress(soketİsmi);

       dinleyici.bind(adres);
       dinleyici.listen(1);
   }

   ~this()
   {
       dinleyici.shutdown(SocketShutdown.BOTH);
       dinleyici.close();
       destroy(dinleyici);
       // Dosyanın silinmesinin gerekip gerekmediğinden aslında emin değilim:
       remove(soketİsmi.toStringz);
   }

   /* Sonsuz döngüde istemci bekler ve ona yanıt verir. */
   void hizmetEt()
   {
       while (true) {
           // İstemci bekliyoruz
           writeln("Bekliyorum...");

           // Şimdi o sokette bağlantı kabul ediyoruz.
           Socket istemci = dinleyici.accept();

           // Bu istemciyle işimiz bittiğinde gereken temizlik işlemi:
           scope (exit) destroy(istemci);

           writeln("Bir istemci bağlandı.");

           // İstemci gidene kadar istemci döngüsündeyiz
           while (istemci.isAlive) {
               string istek = istemci.tekParçaOlarakOku();

               string yanıt = format("(%s)", istek);
               istemci.send(yanıt);

               if (istek == "bitti") {
                   break;
               }
           }

           writeln("Bu istemciyle işim bitti.");
       }
   }
}

/* Socket.receive'in aksine, okunan parçaları birleştirir ve tek string olarak
* döndürür. */
string tekParçaOlarakOku(Socket soket)
{
   string okunan;

   // Okunan veriyi parça parça bu belleğe alacağız
   ubyte[1000] parça;
   bool bütünVeriOkundu_mu = false;

   while (!bütünVeriOkundu_mu) {
       const adet = soket.receive(parça);

       if (adet == Socket.ERROR) {
           stderr.writeln("OKUMA HATASI");
           break;
       }

       okunan ~= parça[0..adet];

       bütünVeriOkundu_mu = (adet < parça.length);
   }

   return okunan;
}

struct İstemci
{
   Socket soket;

   this(string soketİsmi)
   {
       soket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
       soket.connect(new UnixAddress(soketİsmi));
   }

   ~this()
   {
       soket.shutdown(SocketShutdown.BOTH);
       soket.close();
       destroy(soket);
   }

   void iste()
   {
       while (true) {
           write("Sunucuya gönderilecek mesajı yazın: ");
           const mesaj = chomp(readln());
           const adet = soket.send(mesaj);
           writefln("%s bayt gönderdim", adet);

           string yanıt = soket.tekParçaOlarakOku();
           writefln("Yanıt aldım: %s", yanıt);

           if (mesaj == "bitti") {
               break;
           }
       }
   }
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Cevap için teşekkür ederim.

Sorun olmazsa bir soru daha sormak istiyorum: Acaba Whatsapp, Skype vb. uygulamaların chat sisteminde güvenlik haricinde bizim bu yaptığımız chat örnek uygulamalarından farkı var mı? Yani güvenliği saymazsak bizim bu chat sisteminden daha mı hızlı çalışıyorlar? Eğer hız vb. farklar varsa bunlar nelerdir ve nasıl yapıyorlar?

Umarım anlatabilmişimdir. Teşekkürler!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Teşekkürler.

Şu anda http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio.html Boost Asio kütüphanesini buldum. Çok daha kolay geldi ve oop yapısında. Bununla devam edeceğim. Bu kütüphane hakkındaki görüşlerinizi alabilir miyim?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Teşekkür ederim.

Zırt pırt soruyorum fakat merak ediyorum: Acaba bu mobil'de native kavramı tam olarak ne oluyor? Yani asıl olarak native uygulamanın Android için Java, iOs için Objective-C veya Swift olduğunu biliyorum. Fakat Qt sitesinde bu platformlara native uygulama yazmaktan bahsediyor. Şimdi Android için java kullanmazsan native yazmış olmuyormuşsun diyorlar ama Qt olur diyor. Bu tam olarak ne demek? Bu arada eğer android'e, ios'a, win phone'a ve blackberry'ye D kullanarakta native uygulama yazabiliyor muyuz? D için CopperSpice geliştirdiklerini zannediyorum. Bu mobil için ne kadar uygundur (+ olarak native gücü verir mi)?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Alıntı (İbrahim):

>

QByteArray bir resmi nasıl tutuyor (veya bir videoyu)?

Adından bir dizi bayt olduğu anlaşılıyor.

Bellekte, diskte, ve başka her yerde bilginin bitlerle ifade edildiğini biliyorsun. Sekiz bit bir araya gelince bayt oluyor ve zaten her şey bir dizi bayt olarak ifade ediliyor. Dolayısıyla, QByteArray veya eşdeğerleri zaten en doğal türlerdir. :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Hayır, hız farkı yok.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Boost saygın bir kütüphanedir. Oradaki her olanak geniş bir programcı kitlesinin onayından geçerek eklenir ve bazıları sonuçta C++ standardına dahil edilir.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 22, 2015

Bu teknolojilere yakın olan arkadaşlar tamamlayacaklardır ama benim bildiğim, native, belirli bir mikroişlemci üzerinde onun dilinde işleyen kod demektir.

Örneğin, Java native işleyen bir dil değildir çünkü java ile üretilen kod belirli bir mikroişlemci için değil, Java Virtual Machine için derlenir. Yani, java kodları asıl mikroişlemcide değil, onun üzerinde oturan sanal bir mikroişlemcide işler.

Qt ise C++ ile yazılmış olduğundan kodları doğrudan mikroişlemcide işler.

Hayır, CopperSpice'ın D ile bir ilgisi yok. CopperSpice, Qt'nin yerine kullanılan bir kütüphane.

D programları o saydığın ortamlarda çalışsa, evet, D native işleyen kodlar üretir ama bildiğim kadarıyla D o ortamlarda rahatça kullanılmıyor. Örneğin, D kodunu gdc ile derleyeceksin ama target olarak ARM belirteceksin, vs. Bildiğim kadarıyla şimdilik genel kullanıma hazır değil.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 23, 2015

sunucu.d, istemci.d şeklinde yazılacak kodlara bi örnek verebilir misiniz. Daha anlaşılır olur heralde.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

October 23, 2015

O verdiğim kod komut satırındaki seçeneklere bağlı olarak hem sunucu olabiliyor hem de istemci. O tek modülü derliyoruz. Derlenen programın ismi 'deneme' ise:
'
$ deneme --rol=sunucu
'
veya
'
$ deneme --rol=istemci
'
Ali

(Ek: Sanırım kodu ikiye ayırmamı istiyorsun. İyi fikir...)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]