Giriş: BrokenPipeError Nedir?
BrokenPipeError
, Python'da bir iletişim kanalı (pipe, soket veya dosya) üzerinden veri göndermeye çalışırken, karşı tarafın bağlantıyı kapatması durumunda ortaya çıkan bir istisna (exception) türüdür. Bu hata, özellikle:
✔ İşlemler arası iletişimde (IPC)
✔ Ağ programlamada (socket programming)
✔ Çoklu thread/process uygulamalarında
yaygın olarak görülür. Bu makalede, BrokenPipeError
'ın nedenlerini, çözüm yöntemlerini ve en iyi uygulamaları detaylıca inceleyeceğiz.
1. BrokenPipeError Ne Zaman Oluşur?
BrokenPipeError
, bir yazma işlemi (write) sırasında, hedefin bağlantıyı kapatması durumunda oluşur. Örneğin:
Örnek: Soket Programlamada BrokenPipeError
import socket # Sunucu tarafı def server(): s = socket.socket() s.bind(("localhost", 1234)) s.listen(1) conn, _ = s.accept() conn.close() # Bağlantıyı hemen kapat # İstemci tarafı def client(): s = socket.socket() s.connect(("localhost", 1234)) try: s.send(b"Merhaba") # BrokenPipeError! except BrokenPipeError as e: print(f"Hata: {e}") # Test import threading threading.Thread(target=server).start() threading.Thread(target=client).start()
Çıktı:
Hata: [Errno 32] Broken pipe
Sebep:
Sunucu bağlantıyı kapattığı için istemci veri gönderemiyor.
2. BrokenPipeError'ın Yaygın Nedenleri
a) Karşı Tarafın Bağlantıyı Kapatması
Sunucu veya istemci erken bağlantıyı sonlandırırsa
BrokenPipeError
oluşur.
b) İşlemler Arası İletişimde (IPC) Hata
multiprocessing.Pipe
kullanırken bir işlem diğerini bekletmeden kapanabilir.
c) Soket Zaman Aşımı (Timeout)
Uzun süre yanıt gelmezse bağlantı kapatılabilir.
3. BrokenPipeError Nasıl Çözülür?
a) Hata Yakalama ve Kontrollü Kapatma
try: s.send(b"Veri") except BrokenPipeError: print("Bağlantı kapatıldı, soketi temizle") s.close()
b) signal
Kullanarak SIGPIPE'ı Yoksayma (Unix/Linux)
import signal signal.signal(signal.SIGPIPE, signal.SIG_DFL) # Varsayılan davranış # veya signal.signal(signal.SIGPIPE, signal.SIG_IGN) # Hatayı yoksay
c) try-finally
ile Kaynakları Serbest Bırakma
s = socket.socket() try: s.connect(("example.com", 80)) s.send(b"GET / HTTP/1.1\r\n\r\n") except BrokenPipeError: print("Bağlantı koptu!") finally: s.close() # Soketi kapat
4. Gerçek Dünya Senaryoları ve Çözümleri
a) HTTP Sunucusunda BrokenPipeError
from http.server import BaseHTTPRequestHandler, HTTPServer class Handler(BaseHTTPRequestHandler): def do_GET(self): try: self.wfile.write(b"Merhaba Dunya!") except BrokenPipeError: print("İstemci bağlantıyı kesti") HTTPServer(("localhost", 8000), Handler).serve_forever()
b) multiprocessing.Pipe
Kullanımı
from multiprocessing import Pipe, Process def child(conn): conn.send(b"Merhaba") conn.close() parent_conn, child_conn = Pipe() p = Process(target=child, args=(child_conn,)) p.start() try: print(parent_conn.recv()) # Veri alındı parent_conn.send(b"Yanit") # BrokenPipeError riski! except BrokenPipeError: print("Child process pipe'ı kapattı") p.join()
5. Performans ve Güvenlik İpuçları
✔ Soketlerde SO_REUSEADDR
ayarını kullanın:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
✔ asyncio
ile asenkron I/O yönetimi yapın:
writer.write(b"data"); await writer.drain()
✔ Kaynak sızıntılarını önlemek için with
kullanın:
with socket.socket() as s: s.connect(("host", port))
Sonuç
✅ BrokenPipeError
, bir kanalın karşı tarafı kapandığında oluşur.
✅ try-except
ile hatayı yakalayıp kaynakları serbest bırakın.
✅ Çoklu işlem/soket uygulamalarında finally
kullanın.
✅ Unix'te SIGPIPE
sinyalini yönetmek için signal
modülünü kullanın.
Sık Sorulan Sorular (SSS)
❓ Windows'ta BrokenPipeError
farklı mıdır?
Evet, Windows'ta
socket.error
şeklinde gelebilir (Python 3.x'teBrokenPipeError
ayrılmıştır).
❓ BrokenPipeError
ile ConnectionResetError
arasındaki fark nedir?
BrokenPipeError
: Yazma sırasında bağlantı kapandı.ConnectionResetError
: Okuma sırasında bağlantı sıfırlandı.
❓ asyncio
kullanırken bu hata alınır mı?
Hayır,
asyncio
bağlantı kopmalarınıConnectionError
olarak yönetir.
Özet Tablo
Yöntem | Avantajlar | Dezavantajlar |
---|---|---|
try-except | Basit ve doğrudan | Tüm senaryoları kapsamaz |
signal.SIG_IGN | Unix'te hatayı tamamen önler | Windows'ta çalışmaz |
with + finally | Kaynak sızıntısını önler | Kod karmaşıklığı artabilir |