Nedir?
- Amaç: İki ayrı program (server ve client) aracılığıyla sinyal tabanlı iletişim kurmak.
server
arka planda çalışır, bir PID numarası üretir.client
, belirli birPID
’ye (server’ın PID’sine) sinyaller (SIGUSR1, SIGUSR2) göndererek bir mesaj iletir.
- Fikir: Her karakteri bit bit sinyallerle iletmek. Örneğin
SIGUSR1
=0
biti,SIGUSR2
=1
biti gibi bir protokol kurmak veya tam tersi. - Çıktı: Server, aldığı sinyalleri toplayarak tam bir mesaj haline getirdikten sonra bu mesajı ekrana yazar.
Nasıl Çalıştım?
- Server Programı
- Başlarken
getpid()
ile kendi PID’sini ekrana yazdırır. signal()
veyasigaction()
fonksiyonlarıyla SIGUSR1 ve SIGUSR2 sinyallerini yakalamak için handler tanımlar.- Her sinyal geldiğinde bir bit bilgisini server’ın hafızasında biriktiririm.
- 8 bit tamamlandığında bu bitleri bir karakter haline dönüştürür ve ekrana basarım. (Gerekirse mesaj bittiğinde yeni satır da eklerim.)
- Başlarken
- Client Programı
- Kullanıcıdan “PID” ve “Metin mesajı” alır (örneğin
./client 12345 "Hello World"
). - Mesajı karakter karakter, her karakteri de bit bit okuyarak uygun sinyali (
SIGUSR1
veyaSIGUSR2
) server’a gönderirim. - Ek olarak, her sinyalin server tarafından işlendiğinden emin olmak için (isteğe bağlı) server’ın gönderdiği cevap sinyalini (ack) beklemek veya bir mikro-sleep koymak gerekebilir. Proje gereksinimlerine göre değişir.
- Kullanıcıdan “PID” ve “Metin mesajı” alır (örneğin
- Bit Mantığı
- Her karakter 8 bit uzunluğunda (örneğin ASCII).
char c
’yi sıfırdan sekize kadar döngüde gezerek,(c >> i) & 1
diyerek her bir bitini çözüyorum.- Bu bit 0’sa
SIGUSR1
, 1’seSIGUSR2
gönderiyorum (veya tam tersi). - Bu şekilde karakterin tüm bitleri gönderildiğinde server o bitleri birleştirip tekrar karakteri oluşturabiliyor.
Zorluklar ve Öğrendiklerim
- Sinyal Kullanımı:
signal()
ya da daha gelişmişsigaction()
işlevini öğrenmek, sinyal handler yazarken re-entrant fonksiyonlara dikkat etmek önem kazandı.- Eşzamanlılık / senkronizasyon sorunları olmaması için bazen ack sinyalleri veya uyku eklemek gerekebiliyor.
- Bit Manipülasyonu:
- Her karakterin bitlerini parçalayıp (
(c >> i) & 1
) sinyal haline dönüştürmek ve server tarafında bunları geri birleştirmek (bit shift) mantığını kavradım.
- Her karakterin bitlerini parçalayıp (
- PID ve Protokol:
- Server’ın PID’sini terminalde göstermek, client’ın bu PID’yi parametre olarak alıp doğru sinyalleri göndermesi.
- Veri aktarım protokolü: Hangi sinyal 0, hangi sinyal 1’i temsil ediyor, mesaj sonu nasıl anlaşılıyor gibi küçük bir “protokol” kurgulamak zorunda kaldım.
- Bellek ve Performans:
- Sinyaller tek tek gittiği için oldukça yavaş bir yöntem, ancak projedeki amaç hız değil, sinyal mekanizmasını ve bit düzeyinde iletişimi öğrenmek.
- Doğru şekilde
usleep
veya benzeri gecikmeler koymazsam veya ack sinyali kullanmazsam, sinyaller üst üste binip veri kaybına yol açabiliyor.
Sonuç ve Kazanımlar
- “Sinyal tabanlı haberleşme”nin temel prensiplerini öğrenerek sistemin en düşük seviyelerinden birinde basit bir “mesaj gönderme” yöntemi kurguladım.
- C dilinde bit manipülasyonu, PID yönetimi, signal handler gibi istemci-sunucu modelinin basit bir sürümünü deneyimledim.
- Bu proje sayesinde ilerleyen aşamalarda ağ programlaması veya IPC (inter-process communication) konularına daha aşina halde geçiş yapabileceğim.
Minitalk, düşük seviye sistem fonksiyonlarının nasıl kullanılabileceğini göstermesi açısından önemli bir adımdı.
Bir yanıt yazın