---
title: 'Barındırıcı, İstemci ve Sunucu'
source: 'https://academia.sh/tr/kurslar/mcp/barindirici-istemci-sunucu'
course: 'Model Bağlam Protokolü ve Araç Ekosistemi'
language: tr
updated: '2026-08-17T18:06:40+00:00'
license: 'CC BY-SA 4.0'
---

# Barındırıcı, İstemci ve Sunucu

Üç rolün sorumluluk dağılımının mesajla sayılması: on kalem üç role dağıtılır, doğru dağılım hiçbir uzlaşma mesajı gerektirmez ve rol sınırını geçen her kalem kapsamı ile uzaklığının çarpımı kadar mesaj ekler. Barındırıcı ile sunucu hiç doğrudan konuşmadığı için aralarındaki uzaklık iki, istemciyle olan uzaklık birdir; araç tanımı barındırıcıya taşınınca 12, istemciye taşınınca 6 mesaj eklenir, izin listesi sunucuya taşınınca 12, bağlam ve durum sunucuya taşınınca 2 mesaj eklenir. On kalemin tamamı tek rolde toplandığında barındırıcıda 51, sunucuda 45, istemcide 33 mesaj birikir, doğru dağılımda ise sıfır. Aynı üç araçlık zincir doğru dağılımda 6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş tutarken oturum sunucuya kaydığında 9, 9, 254 ve 12 olur, izin listesi sunucuya kaydığında 12, 12, 341 ve 15 olur; iki farklı abonenin koşumu aynı sayımı verir.

Önceki derste üç rol adlandırıldı ve aralarındaki mesajlar sayıldı: aynı üç araçlık zincir
protokolsüz tabanda sıfır mesajla, protokollü kurulumda 6 istek, 6 yanıt, 179 zarf belirteci ve
9 gidiş-dönüşle 844 sonucunu verdi. Adlandırma yapıldı, dağılım yapılmadı. İzin listesi
barındırıcıda mı istemcide mi durur, araç tanımının tek doğru yeri neresidir, oturumu kim tutar,
onayı kim ister?

Bu soruların yanıtı bir üslup tercihi değildir. Bir kalem yanlış rolde durduğunda o kalemi
kullanan taraf onu **elinde tutmaz**, karşı tarafa sormak zorunda kalır; her sorma bir istek, her
yanıt bir mesajdır. Sorumluluk dağılımı bu yüzden sayılabilir bir şeydir: **doğru dağılım, hiçbir
kalemin uzlaşma mesajı gerektirmediği dağılımdır** ve yanlış dağılımın bedeli mesaj cinsinden
yazılır. Bu ders on kalemi üç role dağıtır, her kalemin sınırı geçtiğinde kaç mesaj eklediğini
sayar ve aynı zinciri dört yerleşimde koşturur.

- **PY10.** Ortam, üç kurgu sunucu ve protokol benzeticisi **kurgudur**; gerçek bir sunucu ya da
  çalışma zamanı çağrılmaz. Tohum **20260218**. Zarfın sabit bedeli sekiz belirteçtir.
- **PY11.** On kalem üç role dağıtılır. **Doğru dağılım**, hiçbir kalemin uzlaşma mesajı
  gerektirmediği dağılımdır ve taban çizgisi budur.
- **PY12.** Barındırıcı ile sunucu **hiç doğrudan konuşmaz**; arada istemci vardır. Bu yüzden
  barındırıcı ile sunucu arasındaki uzaklık **iki**, istemciyle olan uzaklık **birdir**.
- **PY13.** Kalemin **kapsamı**, kaç kez uzlaşılması gerektiğidir: sunucu başına ya da çağrı başına
  olan kalemlerde **üç**, oturum başına olanlarda **bir**.
- **PY14.** Kalemin **biçimi** iki değer alır: **çift** bir istek ile bir yanıt, **tek** ise
  yanıtsız bir bildirim üretir.
- **PY15.** Eklenen mesajlar **yerel aktarım fiyatıyla** sayılır; uzak aktarımda gidiş-dönüş iki
  katıdır ve bu ders yalnız **alt sınırı** basar.
- **PY16.** Sayımlar koşumdan bağımsızdır; ikinci koşum aynı dört yerleşimi **başka bir abone**
  için çalıştırır. Bu ders oran basmaz, **sayım** basar; bildirilen beş araçlık kümenin
  çözünürlüğü burada bağlayıcı değildir.
- **PY17.** İzin listesinin ve onay noktasının kendi ölçümü Yapay Zekâ Ajanları kursunda yapıldı ve
  **tekrarlanmaz**: izin listesi tam yetkiye göre başarımı 0,9583'ten 0,8333'e indirmiş, 20 çağrıyı
  durdurmuştu. Burada ölçülen şey o kalemin **yerinin** bedelidir.

## Kalemin Doğru Rolü

**Sunucuda duran üç kalem** araç tanımı, araç yürütmesi ve yetenek bildirimidir. Ortak yanları
şudur: üçü de **aracın kendisine** aittir ve araç değiştiğinde birlikte değişirler. Bir aracın
alan adları değiştiğinde tanım, işleyici ve bildirim aynı anda güncellenir; üçü ayrı yerlerde
dururlarsa değişiklik üç yerde eşzamanlı yapılmak zorundadır.

**İstemcide duran üç kalem** oturum, zarflama ile sayım ve aktarım seçimidir. Ortak yanları şudur:
üçü de **bağlantıya** aittir, araca değil. Bir sunucunun yerel mi uzak mı olduğu ne barındırıcıyı
ne aracı ilgilendirir; ikisi de aynı sonucu bekler. Aktarım seçimi barındırıcıya taşınırsa
barındırıcı her sunucunun bağlantı biçimini bilmek zorunda kalır ve sunucu sayısı değiştikçe
barındırıcı değişir.

**Barındırıcıda duran dört kalem** izin listesi, onay noktası, bağlam ile durum ve model
çağrısıdır. Ortak yanları şudur: dördü de **kullanıcıya ve karara** aittir. Bu grubun en kritik
üyesi izin listesidir: bir sunucuya "hangi araçlara izniniz var" diye sorulamaz, çünkü sunucu kendi
yetki yüzeyini kendisi belirlerse izin listesi diye bir şey kalmaz. Yetki kararı, o kararın sonucuna
katlanacak tarafta durur.

Aşağıdaki kod önceki dersin kurgu ortamını ve benzeticisini kurar, sonra on kalemi bir tabloya
yazar. `tasi`, bir kalemi başka bir role koyduğunda iki tarafın onu birbirine anlatması için gereken
mesajları gerçekten üretir; sayı `mesafe` ile `kapsam` çarpımından gelir.

```python
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def belirtecle(m):
    b = []
    for s in str(m).lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU ortam: olcum aginin abone kayitlari
BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
ABONE = {}
for i in range(60):
    r = uretec(TOHUM + 31 * i)
    onceki = 10000 + int(r() * 80000)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "onceki": onceki, "simdiki": onceki + int(r() * 70)}
BASAMAK, USTU, ISYERI_KAT = ((10, 4), (25, 7), (40, 11)), 16, 2


def _bedel(m3, tip):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    return (top + kalan * USTU) * (ISYERI_KAT if tip == "isyeri" else 1)


def t_sayac(abone=None, **_):
    a = ABONE.get(abone)
    return {"hata": "abone yok"} if a is None else {
        "onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"]}


def t_tuketim(onceki=None, simdiki=None, **_):
    if onceki is None or simdiki is None:
        return {"hata": "eksik alan"}
    f = simdiki - onceki
    return {"m3": f + 100000 if f < 0 else f}


def t_tarife(m3=None, tip="mesken", **_):
    return {"hata": "eksik alan"} if m3 is None else {"tutar": _bedel(m3, tip)}


def t_bolge(bolge=None, **_):
    if bolge not in BOLGE:
        return {"hata": "bolge yok"}
    n = sum(1 for a in ABONE.values() if a["bolge"] == bolge)
    return {"bolge": bolge, "abone": n}


def t_kayit(abone=None, sutun=None, deger=None, **_):
    if not (abone and sutun and deger is not None):
        return {"hata": "eksik alan"}
    return {"yazildi": True}


# ---- KURGU sunucular: her biri yetenek bildirir
SUNUCU = {
    "olcum": {"surum": 2, "aktarim": "yerel",
              "arac": {"sayac_oku": {"islev": t_sayac, "alan": ("abone",), "yan_etki": False},
                       "tuketim": {"islev": t_tuketim, "alan": ("onceki", "simdiki"),
                                   "yan_etki": False}},
              "kaynak": ("abone_listesi",), "istem": ()},
    "tarife": {"surum": 1, "aktarim": "uzak",
               "arac": {"tarife": {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False}},
               "kaynak": ("basamak_tablosu",), "istem": ("bedel_aciklamasi",)},
    "kayit": {"surum": 3, "aktarim": "uzak",
              "arac": {"bolge_ozet": {"islev": t_bolge, "alan": ("bolge",), "yan_etki": False},
                       "kayit_yaz": {"islev": t_kayit, "alan": ("abone", "sutun", "deger"),
                                     "yan_etki": True}},
              "kaynak": (), "istem": ()},
}
ISTEMCI_SURUM = {"olcum": 2, "tarife": 1, "kayit": 2}      # kayit sunucusu ileride
IZIN = ("sayac_oku", "tuketim", "tarife", "bolge_ozet")     # kayit_yaz izin listesinde yok

SAYIM = {"istek": 0, "yanit": 0, "bildirim": 0, "belirtec": 0, "gidis_donus": 0}


def mesaj(tur, govde, aktarim="yerel"):
    """KURGU zarf. Gercek bir protokol uygulanmaz; sayilan sey zarfin bedelidir."""
    SAYIM[tur] += 1
    b = len(belirtecle(govde)) + 8                       # zarf sabiti
    SAYIM["belirtec"] += b
    if tur == "istek":
        SAYIM["gidis_donus"] += 2 if aktarim == "uzak" else 1
    return b


def elsikismasi(istemci_surum=None, izin=None):
    """Yetenek uzlasmasi: surum uyusmazligi ve izin listesi arac kumesini daraltir."""
    istemci_surum = ISTEMCI_SURUM if istemci_surum is None else istemci_surum
    izin = IZIN if izin is None else izin
    anlasilan, dusen = {}, []
    for ad, s in SUNUCU.items():
        mesaj("istek", f"yetenek sor {ad}", s["aktarim"])
        mesaj("yanit", f"yetenek bildir {ad} surum {s['surum']} "
                       + " ".join(s["arac"]) + " " + " ".join(s["kaynak"]))
        if istemci_surum.get(ad, 0) < s["surum"]:
            dusen.append((ad, "surum", s["surum"], istemci_surum.get(ad, 0)))
            continue
        for t, tan in s["arac"].items():
            if t not in izin:
                dusen.append((ad, "izin", t, None))
                continue
            anlasilan[t] = dict(tan, sunucu=ad, aktarim=s["aktarim"])
    return anlasilan, dusen


def cagir(anlasilan, ad, durum):
    if ad not in anlasilan:
        return {"hata": "arac bildirilmedi"}
    t = anlasilan[ad]
    kw = {a: durum[a] for a in t["alan"] if a in durum}
    mesaj("istek", f"{ad} " + " ".join(f"{k} {v}" for k, v in kw.items()), t["aktarim"])
    s = t["islev"](**kw)
    mesaj("yanit", " ".join(f"{k} {v}" for k, v in s.items()))
    return s


# ---- KURGU sorumluluk dagilimi: kalem -> (dogru rol , kapsam , mesaj bicimi)
ROL = ("barindirici", "istemci", "sunucu")
KALEM = {
    "arac tanimi":       ("sunucu", 3, 2), "arac yurutmesi":  ("sunucu", 3, 2),
    "yetenek bildirimi": ("sunucu", 3, 2), "oturum":          ("istemci", 3, 2),
    "zarflama ve sayim": ("istemci", 3, 1), "aktarim secimi":  ("istemci", 3, 2),
    "izin listesi":      ("barindirici", 3, 2), "onay noktasi": ("barindirici", 3, 2),
    "baglam ve durum":   ("barindirici", 1, 1), "model cagrisi": ("barindirici", 1, 2),
}


def mesafe(a, b):
    """Barindirici ile sunucu hic dogrudan konusmaz; arada istemci vardir."""
    return 0 if a == b else (1 if "istemci" in (a, b) else 2)


def tasi(kalem, yeni_rol):
    """Kalem dogru rolunun disinda durursa iki taraf onu her kapsam biriminde
    birbirine anlatir; ciftte istek ve yanit, tekte tek yonlu bildirim."""
    dogru, kapsam, bicim = KALEM[kalem]
    n = mesafe(dogru, yeni_rol) * kapsam
    for i in range(n):
        if bicim == 2:
            mesaj("istek", f"{kalem} uzlas {i}")
            mesaj("yanit", f"{kalem} uzlasildi {i}")
        else:
            mesaj("bildirim", f"{kalem} bildir {i}")
    return n * bicim


print(f"{'kalem':<19}{'dogru rol':<14}" + "".join(f"{r + 'de':>15}" for r in ROL))
toplam = dict.fromkeys(ROL, 0)
for k, (dogru, kapsam, bicim) in KALEM.items():
    ek = []
    for r in ROL:
        for j in SAYIM:
            SAYIM[j] = 0
        ek.append(tasi(k, r))
        toplam[r] += ek[-1]
    print(f"{k:<19}{dogru:<14}" + "".join(f"{e:>15}" for e in ek))
print(f"{'rol basina kalem':<19}{'':<14}"
      + "".join(f"{sum(1 for v in KALEM.values() if v[0] == r):>15}" for r in ROL))
print(f"{'tumu tek rolde':<19}{'':<14}" + "".join(f"{toplam[r]:>15}" for r in ROL))
```

```
kalem              dogru rol       barindiricide      istemcide       sunucude
arac tanimi        sunucu                     12              6              0
arac yurutmesi     sunucu                     12              6              0
yetenek bildirimi  sunucu                     12              6              0
oturum             istemci                     6              0              6
zarflama ve sayim  istemci                     3              0              3
aktarim secimi     istemci                     6              0              6
izin listesi       barindirici                 0              6             12
onay noktasi       barindirici                 0              6             12
baglam ve durum    barindirici                 0              1              2
model cagrisi      barindirici                 0              2              4
rol basina kalem                               4              3              3
tumu tek rolde                                51             33             45
```

## Rol Sınırını Geçmenin Bedeli

Tablonun köşegeni sıfırdır: her kalem kendi doğru rolünde durduğunda hiçbir uzlaşma mesajı
gerekmez. Dağılım dört kalemi barındırıcıya, üçünü istemciye, üçünü sunucuya veriyor. Bu dağılım
bir zevk meselesi değil, sıfır sütununun tanımıdır.

Sayılar iki çarpandan gelir. Birincisi **uzaklıktır**: araç tanımı istemciye kaydığında 6, ta
barındırıcıya kaydığında 12 mesaj ekliyor. Aradaki iki kat, barındırıcı ile sunucunun hiç
doğrudan konuşmamasından gelir; barındırıcıya giden her bilgi istemciden bir kez daha geçer.
İkincisi **kapsamdır**: izin listesi çağrı başına uzlaşılması gereken bir kalemdir ve sunucuya
kaydığında 12 mesaj ekler, oysa bağlam ile durum oturum başına bir kez uzlaşılır ve aynı sınırı
geçtiğinde yalnız 2 bildirim ekler. Aynı yanlışlık, kapsamı büyük kalemde altı kat pahalıdır.

Son satır dağılımın toplam sayısıdır. On kalemin tamamı barındırıcıya toplanırsa **51 mesaj**,
sunucuya toplanırsa **45**, istemciye toplanırsa **33** mesaj birikiyor; doğru dağılımda **sıfır**.
İstemcinin en ucuz toplanma yeri olması rastlantı değildir: istemci ikisinin ortasındadır ve hiçbir
kaleme iki adım uzakta değildir. Bu, her şeyi istemciye yığmanın doğru olduğu anlamına gelmez —
üçüncü satırdaki 33 mesaj hâlâ ödenmiş bir bedeldir ve bu ders yalnız mesajı sayar, izin listesi
sunucuya kaydığında **kimin karar verdiğinin** değiştiğini saymaz.

## Aynı Zincir, Dört Yerleşim

Tablo kalemleri tek tek ölçtü. Aşağıdaki kod aynı üç araçlık zinciri dört farklı yerleşimle
baştan sona koşturur ve toplam sayımı basar. İkinci koşum aynı dört yerleşimi başka bir abone için
tekrarlar.

```python
DOGRU = {k: v[0] for k, v in KALEM.items()}
SENARYO = [("dogru dagilim", DOGRU),
           ("oturum sunucuda", dict(DOGRU, **{"oturum": "sunucu"})),
           ("izin listesi sunucuda", dict(DOGRU, **{"izin listesi": "sunucu"})),
           ("arac tanimi barindiricida", dict(DOGRU, **{"arac tanimi": "barindirici"}))]


def kurulum(yerlesim, abone):
    """Ayni ucluk zincir; tek fark kalemlerin hangi rolde durdugu."""
    for k in SAYIM:
        SAYIM[k] = 0
    for kalem, rol in yerlesim.items():
        tasi(kalem, rol)
    anlasilan, _ = elsikismasi()
    durum = {"abone": abone}
    for ad in ("sayac_oku", "tuketim", "tarife"):
        durum.update(cagir(anlasilan, ad, durum))
    return durum["tutar"], dict(SAYIM)


print("abone  yerlesim                    sonuc  istek  yanit  bildirim"
      "  zarf belirteci  gidis-donus")
for abone in ("A017", "A031"):
    for ad, y in SENARYO:
        t, s = kurulum(y, abone)
        print(f"{abone}   {ad:<26} {t:>5} {s['istek']:>6} {s['yanit']:>6}"
              f" {s['bildirim']:>9} {s['belirtec']:>15} {s['gidis_donus']:>12}")
```

```
abone  yerlesim                    sonuc  istek  yanit  bildirim  zarf belirteci  gidis-donus
A017   dogru dagilim                844      6      6         0             179            9
A017   oturum sunucuda              844      9      9         0             254           12
A017   izin listesi sunucuda        844     12     12         0             341           15
A017   arac tanimi barindiricida    844     12     12         0             341           15
A031   dogru dagilim                 89      6      6         0             179            9
A031   oturum sunucuda               89      9      9         0             254           12
A031   izin listesi sunucuda         89     12     12         0             341           15
A031   arac tanimi barindiricida     89     12     12         0             341           15
```

Dört yerleşim **aynı sonucu** veriyor: A017 için 844, A031 için 89. Yerleşim hesabı değiştirmez,
yalnız fiyatını değiştirir. Doğru dağılımda zincir 179 zarf belirteci tutuyor; tek bir kalem bir
sınır kaydığında 254'e, iki adım kaydığında 341'e çıkıyor. Bir kalemin yanlış rolde durması, işin
kendisini iki katına yakın pahalılaştırıyor ve zincirin gidiş-dönüşü dokuzdan on beşe yükseliyor.

Üçüncü ve dördüncü satırların **aynı olması** öğreticidir. İzin listesi barındırıcıdan sunucuya,
araç tanımı sunucudan barındırıcıya kayıyor; yönler zıt, sayılar birebir aynı. Bedeli belirleyen
şey kalemin ne olduğu değil, **kaç sınır geçtiği ve kaç kez uzlaşıldığıdır**. İki yerleşim mesaj
cinsinden ayırt edilemez; ayırt eden şey mesaj değil, yetki kararının kimde durduğudur ve o bu
tabloda görünmez.

İki abonenin dört satırı da birebir aynı. Yerleşimin bedeli veriye bağlı değildir; sözleşmenin
biçimine bağlıdır. Bir araç bağlantısının sayısı aracın sayısı değil sözleşmenin sayısıdır.

## Özet

- Üç rolün doğru dağılımı, hiçbir kalemin uzlaşma mesajı gerektirmediği dağılımdır: dört kalem
  barındırıcıda, üçü istemcide, üçü sunucuda durur.
- Sunucudaki kalemler araca, istemcidekiler bağlantıya, barındırıcıdakiler kullanıcıya ve karara
  aittir; izin listesi sunucuya sorulamaz, çünkü kararın sonucuna katlanan taraf barındırıcıdır.
- Rol sınırını geçen bir kalem, uzaklık ile kapsamın çarpımı kadar mesaj ekler: araç tanımı
  istemciye kayınca 6, barındırıcıya kayınca 12 mesaj; bağlam ile durum sunucuya kayınca 2 bildirim.
- Barındırıcı ile sunucu hiç doğrudan konuşmadığı için aradaki uzaklık ikidir ve bu, iki uçtaki
  kalemlerin yanlış yerleşimini iki kat pahalı yapar.
- On kalemin tamamı tek rolde toplanırsa barındırıcıda 51, sunucuda 45, istemcide 33 mesaj birikir;
  doğru dağılımda sıfır.
- Aynı zincir doğru dağılımda 179 zarf belirteci ve 9 gidiş-dönüş, izin listesi sunucuya kayınca
  341 zarf belirteci ve 15 gidiş-dönüş tutar; iki abone için sayım birebir aynıdır.

## Sonraki Adım

Bu derste yerleşim değişti, aktarım değişmedi: `olcum` yerelde, `tarife` ile `kayit` uzakta
duruyordu ve eklenen bütün mesajlar yerel fiyatla sayıldı. Oysa gidiş-dönüş sütunu istek sütunundan
bağımsız hareket ediyor; doğru dağılımda 6 istek 9 gidiş-dönüş üretti. Bu farkın kaynağı
aktarımdır ve tek başına ölçülmeyi hak eder. Sonraki ders aynı iş yükünü üç aktarım kurulumunda
koşturur: hepsi yerel, hepsi uzak ve ikisinin karışımı. İstek sayısı sabit kalırken gidiş-dönüşün
ne yaptığı orada görünecek.
