Forum: Ders Arası RSS
Tango soket örneğinin Phobos karşılığı
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Tango soket örneğinin Phobos karşılığı
Şurada güzel bir Tango örneği var:

  http://www.dsource.org/projects/tango/wiki/SocketHelloExam…
// Tango örneği
/*******************************************************************************
 
        Shows how to create a basic socket client, and how to converse with
        a remote server. The server must be running for this to succeed
 
*******************************************************************************/
 
private import  tango.io.Console;
 
private import  tango.net.device.Socket, 
                tango.net.device.Berkeley;
 
void main()
{
        // make a connection request to the server
        auto request = new Socket;
        request.connect (new IPv4Address ("localhost", 8080));
        request.output.write ("hello\n");
 
        // wait for response (there is an optional timeout supported)
        char[64] response;
        size_t len = request.input.read (response);
        // trim the length of the response
        auto received = response[0..len];
        
        // close socket
        request.close;
 
        // display server response
        Cout (received).newline;
}
Aynı kodun Phobos karşılığı şöyle oluyor:
// Phobos örneği
/*******************************************************************************
 
        Shows how to create a basic socket client, and how to converse with
        a remote server. The server must be running for this to succeed
 
*******************************************************************************/
 
private import std.stdio;
 
private import std.socket;
 
void main()
{
    // make a connection request to the server
    auto request = new TcpSocket();
    request.connect (new InternetAddress("localhost", 8080));
    request.send("hello\n");
 
    // wait for response (there is an optional timeout supported)
    char[64] response;
    size_t len = request.receive(response);
    // trim the length of the response
    auto received = response[0..len];
 
    // close socket
    request.close;
 
    // display server response
    writeln(received);
}
Ali
darkofpain #2
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler acehreli,

Ancak verdiğiniz phobos örneği çalışmıyor.

Merak ettiğim için soruyorum. Internet adresi için sınıf çağırmışsınız sonra o sınıfın değişkenini aşağıda kullandınız direk yazsak olmuyor mu ?

Kod ile örnek.

 auto request = new TcpSocket();
    request.connect (new InternetAddress("localhost", 8080));
    request.send("hello\n");

yerine

 auto request = new TcpSocket();
    request.connect ("localhost", 8080);
    request.send("hello\n");

Sizden ricam phobos örneğinde her satırın yanında açıklama satırı ile ne işe yaradıklarını yazarsanız harika olacaktır.

Yada socket programlama üzerinde güzel bir dökümantasyon dlang.org üzerinde verdiğiniz örneğe rastladım orada

import std.stdio;
import std.socket;
 
void main() {
    Socket server = new TcpSocket();
    server.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, 
true);
    server.bind(new InternetAddress(8080));
    server.listen(1);
 
    while(true) {
        Socket client = server.accept();
 
        char[1024] buffer;
        auto received = client.receive(buffer);
 
        writefln("The client said:\n%s", buffer[0.. received]);
 
        enum header =
            "HTTP/1.0 200 OK\nContent-Type: text/html; charset=utf-8\n\n";
 
        string response = header ~ "Hello World!\n";
        client.send(response);
 
        client.shutdown(SocketShutdown.BOTH);
        client.close();
    }
}

bu şekilde kod örneği vermişsiniz. burada verdiğinizden biraz farklı mesela bu kod örneğinde

server.bind(new InternetAddress(8080)); // ne iş yapar
    server.listen(1)// ne iş yapar ? 

gibisinden bilgilendirme olursa çok anlamlı olacaktır sanırım.
Bu mesaj darkofpain tarafından değiştirildi; zaman: 2013-09-08, 08:40.
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
batuhangoksu:
Ancak verdiğiniz phobos örneği çalışmıyor.

Acaba dış etkenlere bağlı bir sorun mu? Çünkü ben tek satırlık kod örnekleri dışında hiçbir kod denemeden koymuyorum. O yüzden genel olarak "çalışmıyor" diyemeyiz. Olsa olsa sende çalışmıyordur. :) Ve her zaman olduğu gibi, "çalışmıyor" yeterli değil. :( Ben "derleniyor ama istenen sonucu vermiyor" diye varsayıyorum.

Bir de tabii bu program kendisine yanıt verecek bir sunucunun çalışmakta olduğunu varsayıyor. (Programın başında "The server must be running for this to succeed" demişler.) Sende 8080 portunu dinleyen bir sunucu var mı?

Internet adresi için sınıf çağırmışsınız sonra o sınıfın değişkenini aşağıda kullandınız direk yazsak olmuyor mu ?

Sen "tango kütüphanesi hakkında" başlıklı olarak açtığın konuda Tango'nun ne kadar kolay bir kütüphane olduğunu savundun diye düşünmüştüm. Örneğin, "tango sadece xml değilde bir çok konuda daha güçlü sanırım", "tango da socket programlamada daha kolay".

Ondan sonra da "Mesela bu kadar basit şekilde phobos ile soket bağlantı nasıl oluyor ?" diye sorunca ben Phobos örneğinin Tango örneğine nasıl bire bir karşılık geldiğini göstermek istedim.

Yani, "new InternetAddress" benim kararım değildi. Tango örneğinde new olduğu için öyle yazdım. :) O örneğe olabildiğince sadık kalmaya çalıştım. Yoksa, daha önce de söylediğim gibi, hiçbir ciddi program soket gibi alt düzey kavramlarla uğraşmak zorunda kalmamalı. Soket işlemleri Sunucu, İstemci, Bağlantı, vs. gibi türlerler sarmalanmalı...

Sizden ricam phobos örneğinde her satırın yanında açıklama satırı ile ne işe yaradıklarını yazarsanız harika olacaktır.

Soket programlama yemek tarifi gibidir. Burada gördüğümüz iki istemci örneği o tarifi uyguluyorlar. O tarifler şurada da var:

  http://www.linuxhowtos.org/C_C++/socket.htm

1) socket() ile soket oluşturulur. Tango ve Phobos socket() sistem çağrısını Socket sınıfı ile sarmalamışlar. (Herhalde sınıfın kurucu işlevi içindedir.)

2) Soket sunucuya connect() ile bağlanır. Tango ve Phobos connect() sistem çağrısını connect() üye işlevi ile sarmalamışlar.

3) Veri gönderilir ve alınır. Tango bu işlemleri nesne üzerinde output.write() ve input.read() olarak sunmuş, Phobos nesne üzerinde send() ve receive() olarak.

dlang.org üzerinde verdiğiniz örneğe rastladım ... bu şekilde kod örneği vermişsiniz. burada verdiğinizden biraz farklı

Evet, dlang.org'da da çok benzer bir soru soruldu:

  http://forum.dlang.org/post/ojcrfufdvdfhbkpyuywo@forum.dla…

Ama dikkat edersen, orada sorulan örnek burada sorulanın aynısı değil. Burada istemci örneği göstermiştin, orada sunucu örneği vardı. O yüzden sorulan örneğe bire bir sadık kalınca doğal olarak programlar farklı oluyor.

server.bind(new InternetAddress(8080)); // ne iş yapar
    server.listen(1)// ne iş yapar ? 

Sunucunun tarifi farklı:

1) socket() ile soket oluşturulur.

2) bind() ile soket bir adrese bağlanır. Bu, sunucunun hangi portu dinleyeceğini bildirmek içindir.

3) listen() ile bağlantı beklemeye başlanır.

4) accept() ile istemcinin bağlanması beklenir.

5) Veri gönderilir ve alınır.

Ali
darkofpain #4
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Teşekkür ederim acehreli güzel yazı oldu.

Hata veriyor şöyleki açıklama yapmadığım için özür dilerim. Derleniyor ancak çalıştırıldığı zaman bu hataları veriyor.

Kodunuz:
private import std.stdio;
 
private import std.socket;
 
void main()
{
    // make a connection request to the server
    auto request = new TcpSocket();
    request.connect (new InternetAddress("localhost", 8080));
    request.send("hello\n");
 
    // wait for response (there is an optional timeout supported)
    char[64] response;
    size_t len = request.receive(response);
    // trim the length of the response
    auto received = response[0..len];
 
    // close socket
    request.close;
 
    // display server response
    writeln(received);
}

Çıkan hatalar.

td.socket.SocketOSException@std/socket.d(2492): Unable to connect socket: Connection refused
----------------
5   deneme                              0x000000010ad58009 _Dmain + 93
6   deneme                              0x000000010ad73555 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runMain() + 33
7   deneme                              0x000000010ad730a1 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate()) + 45
8   deneme                              0x000000010ad735a1 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll() + 61
9   deneme                              0x000000010ad730a1 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate()) + 45
10  deneme                              0x000000010ad73055 _d_run_main + 457
11  deneme                              0x000000010ad72e84 main + 20
12  libdyld.dylib                       0x00007fff9345f7e1 start + 0
13  ???                                 0x0000000000000001 0x0 + 1
----------------
logout
 
[Process completed]


Bir server olmalı dediğiniz için Nginx açıkken test ettim ama fark eden birşey olmadı.
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Nginx 8080 portunu mu dinliyor?

dlang.org'da verdiğim sunucuyu kullanabilirsin:
import std.stdio;
import std.socket;
 
void main() {
    Socket server = new TcpSocket();
    server.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);
    server.bind(new InternetAddress(8080));
    server.listen(1);
 
    while(true) {
        Socket client = server.accept();
 
        char[1024] buffer;
        auto received = client.receive(buffer);
 
        writefln("The client said:\n%s", buffer[0.. received]);
 
        enum header =
            "HTTP/1.0 200 OK\nContent-Type: text/html; charset=utf-8\n\n";
 
        string response = header ~ "Hello World!\n";
        client.send(response);
 
        client.shutdown(SocketShutdown.BOTH);
        client.close();
    }
}
Yukarıdaki programı derle, adını örneğin sunucu koy, ve çalıştır. Hazır olarak istemci bekleyecek...

Ondan sonra yukarıda senin gösterdiğin istemci programı derle ve çalıştır. Sunucu her bağlantıya karşılık içinde "Hello World!" olan bir HTTP yanıtı gönderecek. (Mesaj kırpık gelirse şaşırma. O, senin ilk gösterdiğin basit Tango örneği yalnızca 64 bayt okuduğu için öyle. Arttırırsan düzelecek.)

Ali
darkofpain #6
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Teşekkür ederim acehreli,

Dediğiniz gibi yaptım çalıştı ancak dikkatimi çeken birşey sanırım Nginx portu dinlemiyor o port üzerinden gelen datayı nasıl okuyor ve istek gönderiyor ki acaba.

Sonuçta dlang.org üzerindeki verdiğiniz bir server ama Nginx de bir server :)

Bir şey daha server.bind(new InternetAddress(8080)); burada sadece portu belirttiğimiz zaman ip adresini otomatikmi alıyor yoksa yazmadığımız zaman default olarak 127.0.0.1 mi geliyor ?
Bu mesaj darkofpain tarafından değiştirildi; zaman: 2013-09-09, 01:49.
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
batuhangoksu:
sanırım Nginx portu dinlemiyor

Tahminen, biz başka değere ayarlamadığımızda standart HTTP portu olan 80'i dinliyordur.

yoksa yazmadığımız zaman default olarak 127.0.0.1 mi geliyor ?

Ben de öyle tahmin ediyorum.

Ali
darkofpain #8
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Teşekkür ederim acehreli güzel yazışma oldu.

Nginx ile tekrar test ettim çalışıyor Nginx üzerinden gelen datayı alıyor.

listen() fonksiyonu bağlantı beklemeye hazırlanıyor bunun içine 1 yazıyorum 1 den yüksek rakam yazdığımız zaman ne olur.
Bu mesaj 2 defa değişti; son değiştiren: darkofpain; zaman: 2013-09-09, 13:51.
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
receive()'e verilen ara belleğin neden belirli bir uzunlukta olduğu ile ilgili bir soru var. Örneğin, aşağıda neden 64 var?

acehreli on 2013-09-05, 11:38:
    char[64] response;
    size_t len = request.receive(response);

Bence bunun iki nedeni var:

1) Geleneksel olarak C soket arayüzü de aynı mantıkla işler. Çağıran ara belleğin uzunluğunu 'len' parametresi ile verir:
       ssize_t recv(int sockfd, void *buf, size_t len, int flags);
recv'in dönüş türü aslında kaç bayt geldiğidir. 64'ten az ise bütün veri alınmış demektir. 64 ise, daha veri kalmış olabilir diye recv tekrar çağrılır.

2) Ara belleğin sınırı olmasa ve ara bellek otomatik olarak büyüse, bozuk işleyen veya kötü niyetli olan bir istemci sunucunun bütün belleğini doldurarak sunucuyu çökertebilirdi.

Daha önceki soket örneklerinde ben kolaylık olsun diye şu işlevi yazmıştım:
/* 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;
}
Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-12-16, 10:49:09 (UTC -08:00)