Bu proje, TCP soket programlama, uygulama katmanı mesaj çerçeveleme, metin ve ikili dosya aktarımı, veri bütünlüğü doğrulaması ve eşzamanlı haberleşme konularını uygulamalı olarak göstermek amacıyla C++17 kullanılarak geliştirilmiştir.
Uygulama, Windows 11 üzerinde WSL2 / Ubuntu 20.04 LTS ortamında çalışır. Sunucu ve istemci aynı TCP bağlantısı üzerinden çift yönlü olarak metin mesajı ve JPG/JPEG/PNG biçimindeki görüntü dosyalarını aktarabilir.
tmuxvechafayalnızca terminal sunumu ve görüntü önizlemesi için kullanılan yardımcı araçlardır. TCP haberleşme katmanı C++17 ile gerçekleştirilmiştir.
Windows PowerShell'i proje klasöründe açın ve tek komut çalıştırın:
.\baslatKomut projeyi derler; bir sunucu ile beş istemciyi düzenli terminal panellerinde açar. Gönderen istemcinin paneline tıklayın ve alıcı seçimini yapın:
3 Yalnız İstemci 3
2,4 İstemci 2 ve 4
0 Gönderen dışındaki bütün istemciler
Seçimden sonra metni doğrudan yazın. Görüntü göndermek için:
!resim foto1.jpg
Tam doğrulama için Ubuntu/WSL terminalinde:
bash 702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_Dosyalari/dogrula.shAyrıntılı kullanım için Çalıştırma Kılavuzu dosyasına bakın.
Projenin temel amacı, TCP'nin güvenilir ve sıralı bayt akışı yapısı üzerinde uygulama seviyesinde bir mesajlaşma protokolü oluşturmaktır. Bu kapsamda sistem aşağıdaki işlevleri gerçekleştirir:
- İstemci ile sunucu arasında TCP bağlantısı kurulması
- Çift yönlü metin mesajı aktarımı
- JPG, JPEG ve PNG görüntü aktarımı
- Mesaj türü ve veri boyutunun özel uygulama başlığı ile taşınması
- Kısmi
send()verecv()işlemlerinin güvenli biçimde tamamlanması - Metin ve görüntüler için CRC32 bütünlük doğrulaması
- Gelen görüntülerin güvenli dosya adıyla kaydedilmesi
- Aynı isimli dosyaların üzerine yazılmasının önlenmesi
- Gönderim ve alım ilerlemesinin terminalde gösterilmesi
- Gelen görüntünün
chafaile terminal içinde önizlenmesi tmuxile sunucu ve beş istemcinin aynı ekranda izlenmesi
Uygulama klasik istemci-sunucu mimarisini kullanır.
┌──────────────────────┐ TCP / IPv4 ┌──────────────────────┐
│ TCP İstemci │ <──────────────────────────> │ TCP Sunucu │
│ 127.0.0.1:dinamik │ 127.0.0.1:5000 │ 0.0.0.0:5000 │
└──────────────────────┘ └──────────────────────┘
│ │
├── Metin gönder / al ├── Metin gönder / al
├── Görüntü gönder / al ├── Görüntü gönder / al
├── CRC32 doğrulama ├── CRC32 doğrulama
└── Alıcı iş parçacığı └── Alıcı iş parçacığı
Sunucu 5000/TCP portunu dinler ve aynı anda en fazla beş istemciyi kabul eder. Her istemciye benzersiz bir bağlantı kimliği atanır. İstemci aktif kimlikleri listeleyip bir hedef seçtikten sonra metin veya görüntüyü yalnız seçilen istemciye gönderir.
TCP mesaj sınırlarını kendiliğinden belirlemez; yalnızca sıralı bir bayt akışı sağlar. Bu nedenle proje, her mesajın başına 13 baytlık sabit bir uygulama üst bilgisi ekler.
| Alan | Boyut | Açıklama |
|---|---|---|
type |
1 bayt | Liste, metin, görüntü, kimlik, liste yanıtı veya hata türü |
client_id |
2 bayt | İstemciden sunucuya hedef, sunucudan alıcıya kaynak kimliği |
filename_len |
2 bayt | Dosya adı uzunluğu; metinde 0 |
data_size |
4 bayt | Gönderilen içeriğin bayt cinsinden boyutu |
checksum |
4 bayt | İçeriğin CRC32 doğrulama değeri |
| Toplam | 13 bayt | Sabit uygulama başlığı |
Sayısal alanlar ağ bayt sırasına dönüştürülür. Bunun için htons(), htonl(), ntohs() ve ntohl() fonksiyonları kullanılır.
Metin mesajının yapısı:
[ 13 bayt başlık ][ metin verisi ]
Görüntü mesajının yapısı:
[ 13 bayt başlık ][ dosya adı ][ görüntü verisi ]
TCP güvenilir aktarım sağlar ancak tek bir send() veya recv() çağrısının istenen tüm baytları aynı anda işleyeceği garanti edilmez. Bu nedenle projede:
send_exact(...)
read_exact(...)fonksiyonları kullanılır. Bu fonksiyonlar, gerekli bayt sayısının tamamı gönderilene veya alınana kadar işlemi döngü içerisinde sürdürür.
Metin ve görüntü içerikleri ayrıca CRC32 ile doğrulanır. Gönderici CRC32 değerini hesaplayarak mesaj başlığına ekler. Alıcı aynı verinin CRC32 değerini yeniden hesaplar ve iki değeri karşılaştırır.
CRC32 bir kriptografik güvenlik veya kimlik doğrulama mekanizması değildir. Bu projede yalnızca aktarım bütünlüğünü denetlemek amacıyla kullanılmaktadır.
Proje dizini, kaynak kod, derleme dosyaları, test verileri, çalışma çıktıları ve proje belgelerinin birbirinden ayrılması amacıyla kurumsal dosyalama yaklaşımına göre düzenlenmiştir.
cpp-tcp-messenger/
│
├── 702_Yazilim_Isleri/
│ └── TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/
│ │
│ ├── 01_Kaynak_Kod_Dosyalari/
│ │ ├── client.cpp
│ │ ├── server.cpp
│ │ ├── protocol.cpp
│ │ ├── protocol.h
│ │ ├── chat_common.h
│ │ └── ui.h
│ │
│ ├── 02_Derleme_ve_Calistirma_Dosyalari/
│ │ ├── Makefile
│ │ ├── calistir.ps1
│ │ ├── calistir.sh
│ │ ├── istemci.sh
│ │ ├── sunucu.sh
│ │ └── Derlenmis_Uygulama_Dosyalari/
│ │ ├── client
│ │ └── server
│ │
│ ├── 03_Test_ve_Dogrulama_Calismalari/
│ │ └── Test_Verileri/
│ │
│ ├── 04_Uygulama_Ciktilari/
│ │ └── Alinan_Dosyalar/
│ │
│ └── 05_Teknik_Dokumantasyon/
│
├── 703_Bilgi_Isletim_Sistemleri_Planlama_ve_Degerlendirme/
│ ├── 01_Proje_Yonetimi/
│ │ └── Proje_Raporlari/
│ │ └── LBLM301_Proje_Raporu.tex
│ │
│ └── 02_Degisiklik_ve_Konfigurasyon_Yonetimi/
│ └── DEGISIKLIK_KAYDI.md
│
├── README.md
└── .gitignore
Derlenmis_Uygulama_Dosyalari/ ve çalışma sırasında oluşturulan alınan dosyalar Git deposuna dahil edilmez.
| Dosya | Sorumluluk |
|---|---|
client.cpp |
TCP istemcisini oluşturur, sunucuya bağlanır ve kullanıcı girişlerini işler. |
server.cpp |
TCP sunucusunu oluşturur, 5000 portunu dinler ve istemci bağlantısını kabul eder. |
protocol.h |
Mesaj türlerini, 13 baytlık başlığı, boyut sınırlarını ve protokol fonksiyon bildirimlerini tanımlar. |
protocol.cpp |
send_exact(), read_exact() ve CRC32 işlemlerinin uygulamasını içerir. |
chat_common.h |
Metin/görüntü gönderme ve alma, dosya doğrulama, güvenli kayıt ve ortak haberleşme mantığını içerir. |
ui.h |
Terminal renkleri, bilgi kartları, ilerleme çubuğu, yardım ekranı ve chafa önizlemesini yönetir. |
Makefile |
Sunucu ve istemci uygulamalarını C++17 ile derler. |
calistir.sh |
Derleme ve tmux tabanlı çift panel çalışma sürecini otomatikleştirir. |
calistir.ps1 |
Windows PowerShell üzerinden WSL2 çalışma sürecini başlatır. |
sunucu.sh |
Derlenmiş sunucu uygulamasını başlatır. |
istemci.sh |
Derlenmiş istemci uygulamasını başlatır. |
| Bileşen | Kullanılan Teknoloji |
|---|---|
| Ana işletim sistemi | Windows 11 |
| Linux ortamı | WSL2 / Ubuntu 20.04 LTS |
| Programlama dili | C++17 |
| Derleyici | GNU g++ |
| Derleme sistemi | GNU Make |
| Ağ protokolü | TCP / IPv4 |
| Varsayılan port | 5000/TCP |
| İş parçacığı | std::thread / pthread |
| Terminal oturumu | tmux |
| Görüntü önizleme | chafa |
| Hata ayıklama | gdb |
Ubuntu 20.04 ortamında temel geliştirme araçları:
sudo apt update
sudo apt install -y build-essential gdb tmux chafaWSL2 dağıtımının adı aşağıdaki komutla kontrol edilebilir:
wsl -l -vBu proje için kullanılan dağıtım:
Ubuntu-20.04
Proje kök dizininden:
make -C 702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_Dosyalari clean
make -C 702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_DosyalariDerleme seçenekleri:
-Wall -Wextra -Wpedantic -std=c++17 -pthread
Başarılı derleme sonucunda aşağıdaki dosyalar oluşturulur:
02_Derleme_ve_Calistirma_Dosyalari/
└── Derlenmis_Uygulama_Dosyalari/
├── server
└── client
Proje kök dizininde:
.\baslatBu işlem projeyi derler ve tmux üzerinde sunucu ile beş istemciyi açar.
./702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_Dosyalari/calistir.shÖnce sunucu:
./702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_Dosyalari/Derlenmis_Uygulama_Dosyalari/serverDaha sonra ikinci terminalde istemci:
./702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_Dosyalari/Derlenmis_Uygulama_Dosyalari/clientNormal metin göndermek için terminale doğrudan mesaj yazılır:
Merhaba TCP
Test görüntüsü göndermek için:
!resim foto1.jpg
Desteklenen komutlar:
| Girdi | İşlev |
|---|---|
3 |
Yalnız İstemci 3'ü alıcı seçer. |
2,4 |
İstemci 2 ve 4'ü birlikte seçer. |
0 |
Gönderen dışındaki bütün istemcileri seçer. |
!liste |
Mesaj gönderilebilecek aktif istemci kimliklerini getirir. |
!hedef <kimlik> |
Metin ve görüntülerin gönderileceği istemciyi seçer. |
!resim <dosya_adı veya dosya_yolu> |
JPG/JPEG/PNG görüntü gönderir. Yalın adlar test klasöründe aranır. |
!durum |
Aktif bağlantı durumunu gösterir. |
!temizle |
Terminal ekranını temizler. |
!yardim |
Kullanılabilir komutları gösterir. |
cikis |
TCP bağlantısını düzenli biçimde kapatır. |
Görüntü gönderilirken uygulama aşağıdaki sırayı izler:
Dosya yolu kontrolü
↓
JPG/JPEG/PNG uzantı kontrolü
↓
Dosya boyutu kontrolü
↓
CRC32 hesaplama
↓
13 baytlık başlığın hazırlanması
↓
Dosya adının gönderilmesi
↓
Görüntü içeriğinin tam gönderilmesi
↓
Alıcıda yeniden CRC32 hesaplama
↓
CRC32 eşleşirse dosyanın kabul edilmesi
↓
Terminalde chafa önizlemesi
Gelen dosyalar aşağıdaki klasöre kaydedilir:
702_Yazilim_Isleri/
└── TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/
└── 04_Uygulama_Ciktilari/
└── Alinan_Dosyalar/
Uygulamada aşağıdaki koruyucu kontroller bulunmaktadır:
- Metin boyutu en fazla 64 KiB
- Görüntü boyutu en fazla 10 MiB
- JPG/JPEG/PNG uzantısı ile dosya imzasının birlikte doğrulanması
- Gelen dosya adının
safe_filename()ile temizlenmesi - Dizin dışına yazmaya yönelik dosya yollarının engellenmesi
- Aynı isimli mevcut dosyanın üzerine yazılmaması
- Eksik TCP aktarımının başarısız kabul edilmesi
- CRC32 uyuşmazlığında bozuk görüntünün silinmesi
- Bilinmeyen mesaj türlerinin reddedilmesi
- Geçersiz başlık alanlarının kontrol edilmesi
Sunucu her istemciyi ayrı bir iş parçacığında yönetir. Aynı hedefe yönlendirilen çerçevelerin karışmaması için her istemcinin gönderim mutex'i bulunur. İstemcide gelen verilerin kullanıcı girişinden bağımsız alınabilmesi için ayrı bir alıcı iş parçacığı oluşturulur:
std::thread receiver(receive_loop, socket_fd);Böylece ana iş parçacığı terminalden kullanıcı girdisini beklerken alıcı iş parçacığı karşı taraftan gelen TCP verisini işlemeye devam eder.
Terminal çıktılarının farklı iş parçacıkları tarafından aynı anda bozulmaması için ui.h içerisinde std::mutex kullanılır.
Neden TCP? Metin ve dosya aktarımında sıralı, güvenilir ve bağlantı tabanlı veri iletimi gerektiği için TCP tercih edilmiştir.
Neden 13 baytlık özel başlık? TCP mesaj sınırlarını bilmediğinden alıcının mesaj türünü, hedef/kaynak kimliğini, dosya adı uzunluğunu, veri boyutunu ve CRC32 değerini önceden bilmesi gerekir.
Neden send_exact() ve read_exact()? Soket API'sinde tek bir send() veya recv() çağrısı istenen tüm veriyi işlemeyebilir. Yardımcı fonksiyonlar, aktarım tamamlanana kadar işlemi sürdürür.
Neden ağ bayt sırası? Çok baytlı sayısal alanların farklı sistem mimarilerinde aynı biçimde yorumlanmasını sağlar.
Neden CRC32? Aktarılan verinin gönderici ve alıcı tarafında aynı olup olmadığını kontrol etmek için kullanılır.
Neden ayrı alıcı iş parçacığı? Kullanıcı klavye girişi beklerken gelen mesajların bloklanmaması için kullanılır.
Neden SO_REUSEADDR? Sunucu yeniden başlatıldığında TCP portunun gereksiz yere kullanılamaz durumda kalması ihtimalini azaltır.
Neden shutdown() ve close()? Bağlantının kontrollü biçimde sonlandırılması ve soket kaynaklarının işletim sistemine geri verilmesi için kullanılır.
| Test | Beklenen Sonuç |
|---|---|
| Kısa metin aktarımı | Metin eksiksiz alınır. |
| Türkçe karakterli metin | İçerik bozulmadan alınır. |
| JPG aktarımı | Görüntü kaydedilir ve CRC32 doğrulanır. |
| PNG aktarımı | Görüntü kaydedilir ve CRC32 doğrulanır. |
| Ardışık mesajlar | Mesaj sınırları birbirine karışmaz. |
| Aynı isimli görüntü | Yeni ve benzersiz dosya adı oluşturulur. |
| Geçersiz dosya yolu | Gönderim başlatılmaz ve hata gösterilir. |
| Desteklenmeyen uzantı | Dosya reddedilir. |
| Boyut sınırı aşımı | Aktarım başlatılmaz. |
| CRC32 uyuşmazlığı | Bozuk veri kabul edilmez. |
| Bağlantı kesilmesi | Eksik aktarım başarılı sayılmaz. |
| Düzenli çıkış | Soket ve iş parçacığı kontrollü biçimde kapatılır. |
Bu sürüm eğitim ve yerel ağ haberleşmesi senaryosu için hazırlanmıştır. Mevcut kapsam:
1 sunucu
En fazla 5 eşzamanlı istemci
Aktif istemci listesi ve özel hedef seçimi
TCP / IPv4
Metin mesajı
JPG / JPEG / PNG görüntü aktarımı
CRC32 bütünlük kontrolü
Yerel çalışma ortamı
Aşağıdaki özellikler mevcut sürümün kapsamı dışındadır:
Kullanıcı hesabı ve oturum sistemi
Veritabanı
Kalıcı mesaj geçmişi
TLS
Uçtan uca şifreleme
Kriptografik kimlik doğrulama
İnternet üzerinden üretim ortamı kullanımı
Derlenmiş programlar ve çalışma çıktıları kaynak kod deposunda tutulmaz. .gitignore üzerinden aşağıdaki içerikler hariç tutulur:
Derlenmis_Uygulama_Dosyalari/
Alinan_Dosyalar/*
*.o
*.gch
*.aux
*.log
*.out
*.toc
.vscode/
Kaynak kod değişiklikleri Git commit geçmişi üzerinden izlenir. Dosya adlarında SON, FINAL, YENI veya GUNCEL gibi manuel sürüm ifadeleri yerine sürüm kontrol sistemi kullanılması hedeflenmiştir.
Muhammed Sina Gün Bilgisayar Mühendisliği LBLM301 Veri Haberleşmesi ve Bilgisayar Ağları Ders Projesi
Bu depo akademik ders projesi kapsamında hazırlanmıştır. Kodun yeniden kullanımı veya geliştirilmesi durumunda proje kaynağının belirtilmesi önerilir.
Temiz derleme, 13 baytlık protokol birim testleri, beş istemcili gerçek TCP yönlendirme testi, görüntü önizlemesi ve VS Code görevleri hazırdır. Güncel başlangıç adımları Çalıştırma Kılavuzu, ayrıntılı test kapsamı Test Kapsamı dosyasındadır. GitHub Actions her gönderimde aynı doğrulamayı çalıştırır.
WSL/Linux terminalinde proje kökünden:
b="702_Yazilim_Isleri/TCP_Tabanli_Metin_ve_Goruntu_Mesajlasma_Uygulamasi/02_Derleme_ve_Calistirma_Dosyalari"
bash "$b/dogrula.sh"
bash "$b/calistir.sh"Gösterimde istemciye !resim piksel_test.png yazın. Yalın dosya adları otomatik olarak
03_Test_ve_Dogrulama_Calismalari/Test_Verileri klasöründe aranır. Windows Gezgini'nden
sürüklenen tırnaklı yollar temizlenir ve C:\... yolları WSL biçimine çevrilir. Alıcı
CRC32 doğrular, dosyayı kaydeder ve renkli piksel bloklarıyla gösterir.
Görseli Windows Gezgini'nden terminale sürükleyip yalnızca Enter'a basmak da yeterlidir;
JPG/JPEG/PNG yolu otomatik olarak görsel aktarımı kabul edilir.