İçeriğe geç
academia.sh

Ders 02 / 12

İstemci–Sunucu Modeli

Bağlantıyı başlatan ile bekleyen rollerinin ayrımı, bağlantı noktası kavramı ve eşler arası modelle karşılaştırma.

İçindekiler

Önceki ders paketlerin ağ üzerinde nasıl taşındığını kurdu ve iletişimi kimin başlattığı sorusunu açık bıraktı. Ağ, iki konağı da aynı biçimde taşır; aralarındaki fark ağın değil, üzerlerinde çalışan programların özelliğidir.

Bu ders o farkı tanımlar: ornek.test sayfasını tutan makinedeki program neden sürekli bekler, sizin makinenizdeki program neden istediği anda konuşmaya başlar? Ders sonunda bu kursun örnek sunucusu çalışır durumda olacak.

Rolleri Ayıran Ölçüt

Sunucu (server), bir bağlantı noktasında bekleyen ve gelen isteklere yanıt veren programdır. İstemci (client), bağlantıyı başlatan ve istek gönderen programdır.

Ayrımın tek ölçütü bağlantıyı kimin başlattığıdır. Yaygın bir yanlış anlama, sunucuyu “güçlü makine”, istemciyi “zayıf makine” saymaktır. Bu doğru değildir: rol donanıma değil, programın davranışına aittir. Aynı makine bir program için sunucu, başka bir program için istemci olabilir; sunucular sık sık başka sunucuların istemcisidir.

Roller iki asimetri doğurur.

Bulunabilirlik. İstemcinin sunucuyu bulabilmesi gerekir; sunucunun istemciyi bilmesine gerek yoktur. Bu yüzden sunucunun adresi kararlı ve önceden bilinir olmak zorundadır. İstemcinin adresi geçici olabilir, bağlantıdan bağlantıya değişebilir.

Erişilebilirlik. Sunucu, istek gelebileceği her an dinliyor olmalıdır. İstemci ise yalnızca konuşacağı anda çalışır. Sunucunun sürekli çalışması gerekliliği, sonraki derslerde ele alınacak barındırma sorununun kaynağıdır.

Bağlantı Noktası

Bir adres makineyi belirler. Ancak bir makinede aynı anda birden çok sunucu programı çalışabilir. Gelen bir paketin hangi programa ait olduğunu ayırt etmek için ikinci bir sayı gerekir: bağlantı noktası (port).

Adres binayı, bağlantı noktası binadaki daireyi gösterir. Bir bağlantı, dört değerle tanımlanır: kaynak adres, kaynak bağlantı noktası, hedef adres, hedef bağlantı noktası. Bu dörtlü benzersiz olduğu sürece aynı iki makine arasında sayısız bağlantı bir arada yaşayabilir.

Sunucular önceden bilinen numaralarda dinler; istemcinin adresi gibi istemcinin bağlantı noktası da genellikle işletim sistemince o an atanan geçici bir numaradır. Web trafiğinin şifrelenmemiş biçimi 80, şifrelenmiş biçimi 443 numaralı bağlantı noktasında dinlenir. Bu numaralar bir kayıt kuruluşunca ayrılmıştır ve adres satırında yazılmadıkları için görünmezler: http://ornek.test/ yazdığınızda 80, https://ornek.test/ yazdığınızda 443 varsayılır.

Farklı bir numara kullanılacaksa adreste açıkça yazılır. Bu kursun örneklerinde 8080 numarası kullanılır; ayrıcalıklı olmayan bir numara seçmek, sunucuyu yönetici yetkisi olmadan çalıştırmayı sağlar.

Bir Sunucu Yazmak

Sunucunun ne yaptığını anlatmanın en kesin yolu bir tane çalıştırmaktır. Aşağıdaki program bir bağlantı noktasında dinler, tek bir bağlantı kabul eder, aldığı baytları ekrana yazar ve sabit bir yanıt gönderir.

import socket

GOVDE = b"<!doctype html>\n<html lang=\"tr\"><body><h1>Ornek Sayfa</h1></body></html>\n"

YANIT = (
    b"HTTP/1.1 200 OK\r\n"
    b"Content-Type: text/html; charset=utf-8\r\n"
    b"Content-Length: " + str(len(GOVDE)).encode() + b"\r\n"
    b"Connection: close\r\n"
    b"\r\n"
) + GOVDE


def sunucuyu_calistir(baglanti_noktasi: int = 8080) -> None:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as dinleyici:
        dinleyici.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        dinleyici.bind(("127.0.0.1", baglanti_noktasi))
        dinleyici.listen(1)
        istemci, adres = dinleyici.accept()
        with istemci:
            istek = istemci.recv(4096)
            print("--- gelen istek ---")
            print(istek.decode("utf-8", "replace"), end="")
            print("--- istek sonu ---")
            istemci.sendall(YANIT)


sunucuyu_calistir()

Program dört adımı sırayla yürütür ve bu dört adım her sunucuda aynıdır:

  1. bind — bir adres ve bağlantı noktası sahiplenilir.
  2. listen — gelen bağlantıları kabul etmeye hazır duruma geçilir.
  3. accept — bir istemci bağlanana kadar beklenir. Bu satırda program durur.
  4. recv / sendall — istek okunur, yanıt yazılır.

Üçüncü adım rolün özüdür. Sunucu, ne zaman ve kimin bağlanacağını bilmeden bekler.

socket çağrılarındaki soket (socket), bir bağlantının program tarafındaki tutamağıdır; işletim sistemi bu tutamak üzerinden veri okunmasını ve yazılmasını sağlar.

Bir İstemci Çalıştırmak

Sunucu çalışırken başka bir uçbirimden bir istemci çalıştırılır. Burada istemci olarak curl kullanılır. --resolve seçeneği, ornek.test adının hangi adrese karşılık geldiğini elle bildirir; ad çözümlemesi sonraki konunun konusudur, burada yerine geçici olarak bu seçenek konur. -A seçeneği istemcinin kendini tanıttığı metni sabitler.

curl -sv --resolve ornek.test:8080:127.0.0.1 -A "ornek-istemci" http://ornek.test:8080/

İstemci tarafında görünen alışveriş (> giden, < gelen satırları gösterir):

* Added ornek.test:8080:127.0.0.1 to DNS cache
* Hostname ornek.test was found in DNS cache
*   Trying 127.0.0.1:8080...
* Connected to ornek.test (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: ornek.test:8080
> User-Agent: ornek-istemci
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 73
< Connection: close
< 
{ [73 bytes data]
* Closing connection
<!doctype html>
<html lang="tr"><body><h1>Ornek Sayfa</h1></body></html>

* ile başlayan satırlar curl’ün kendi açıklamalarıdır, alışverişin parçası değildir.

Sunucu tarafında ise istemcinin gönderdiği baytlar göründü:

--- gelen istek ---
GET / HTTP/1.1
Host: ornek.test:8080
User-Agent: ornek-istemci
Accept: */*

--- istek sonu ---

İki çıktı aynı alışverişin iki ucudur. Dikkat edilecek nokta, sunucunun aldığı şeyin yapılandırılmış bir nesne değil, düz bir metin olmasıdır. İstek de yanıt da baytlardan oluşur; kuralları belirleyen tek şey iki tarafın aynı biçimi izlemesidir. O biçim HTTP’dir ve üçüncü konunun konusudur.

127.0.0.1 adresi makinenin kendisini gösterir; bu adrese gönderilen paketler makineden çıkmaz. Bu, gerçek bir ağa gerek kalmadan istemci–sunucu alışverişinin bütününü incelemeyi sağlar.

Eşler Arası Model

İstemci–sunucu tek seçenek değildir. Eşler arası (peer-to-peer) modelde her konak hem istemci hem sunucu gibi davranır: kaynağı hem alır hem başkalarına sunar. Merkezde duran ayrıcalıklı bir makine yoktur.

İki model, aynı ölçütler üzerinden karşılaştırılır.

Ölçüt İstemci–sunucu Eşler arası
Kaynağın yeri Bilinen bir konakta Katılan konaklara dağılmış
Bulma yöntemi Sunucunun adresi bilinir Eşlerin listesi keşfedilir
Talep artınca Sunucu yükü artar Kapasite de artar
Tek arıza noktası Sunucu Yok
Denetim ve tutarlılık Tek yerde, kolay Dağıtık, güç
Erişilebilirlik Sunucuya bağlı Yeterli eş varsa sürer

Eşler arası modelin en belirgin üstünlüğü ölçeklenmedir: kaynağı isteyen her yeni konak, aynı zamanda o kaynağı sunabilecek yeni bir kapasitedir. Talep arttıkça arz da artar.

Buna karşılık iki güçlüğü vardır. Birincisi bulunabilirliktir: kararlı bir adres olmadığında bir kaynağın kimde bulunduğunu saptamak ayrı bir problemdir. İkincisi denetimdir: içeriğin doğruluğunu, güncelliğini ve yetkilendirmesini tek bir noktadan güvence altına almak dağıtık bir yapıda güçtür.

Web, istemci–sunucu modeli üzerine kuruludur. Gerekçe, bu iki güçlüğün web’in temel gereksinimleriyle doğrudan çakışmasıdır: bir alan adının belirli bir içeriği göstermesi beklenir ve o içeriğin kimin yetkisinde olduğu belirli olmalıdır. Kararlı ad ve kararlı sorumluluk, kararlı bir sunucu gerektirir.

Bu ayrım keskin bir sınır değildir. Bir sunucunun ardında yükü paylaşan çok sayıda makine bulunabilir; iki tarayıcı arasında doğrudan bağlantı kurulabilir. Roller, makinelere değil belirli bir alışverişe göre belirlenir.

Özet

  • İstemci ile sunucuyu ayıran ölçüt donanım değil, bağlantıyı kimin başlattığıdır.
  • Sunucu kararlı bir adreste sürekli dinler; istemcinin adresi geçici olabilir.
  • Bağlantı noktası, aynı makinedeki birden çok sunucu programını ayırır; bir bağlantı kaynak ve hedef adres ile bağlantı noktalarından oluşan dörtlüyle tanımlanır.
  • Bir sunucu programı bind, listen, accept ve okuma/yazma adımlarını izler; accept çağrısında beklemek rolün özüdür.
  • İstek ve yanıt yapılandırılmış nesneler değil, iki tarafın aynı biçimde yorumladığı bayt dizileridir.
  • Eşler arası model talep arttıkça kapasite kazandırır, ancak kararlı adres ve merkezî denetim gerektiren web için istemci–sunucu modeli seçilmiştir.

Sonraki Adım

Sunucunun kararlı bir adreste dinlemesi gerektiği kuruldu; ancak bu sunucu sizin makinenizle aynı yerel ağda değildir. Aradaki paketler, birbirinden bağımsız işletilen çok sayıda ağdan geçer ve bu ağların ortak bir sahibi yoktur. Sonraki ders, tek bir kuruluşa ait olmayan bu yapının nasıl bir arada durduğunu ve ornek.test sunucusuna giden yolun kimler tarafından belirlendiğini ele alacak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat