TCP sunucu paketlerin bazan yarım gelmesi sorunu

turkuazaga

Üye
Katılım
23 Aralık 2018
Mesajlar
58
TCP sunucuyu neredeyse tamamladım. Sunucuyu çalıştırıyorum sonra da telnet ile bağlanıp bir satır yazıyorum ve enter'a basıyorum. Sunucu da bu satırı alıyor ve geri gönderiyor, telnet ekranında kendi yazdığım satırın geri geldiğini görüyorum. Ama bazan sunucu benim yazdığım satırı ikiye bölüyor ve iki ayrı satır olarak telnet'e geri geliyor. Bu çok sık olmuyor, ama ne bileyim, 20 denemede 1 defa oluyor. Bunun sebebi ne olabilir?
 
TCP protokolü, veri gönderilirken kaç byte'lık parçalar halinde gönderileceğine dair hiçbir garanti vermez. Soketten sana ne kadar data verildiyse onu alır biriktirirsin. Bu sistem, eğer örneğin bir dosya download edilecekse, hiçbir sorun teşkil etmez. Okumaya başlarsın, data geldikçe okur ve gelen dataları diske yazarsın. Data kesildiği anda da diskteki dosyayı kapatırsın iş biter. Data 64 KByte'lık paketler halinde gelmiş veya 4096 byte'lik paketler halinde gelmiş aldırmazsın.

Ama eğer gönderilen verinin belli bir yapısı varsa, örneğin 1024 byte'lık sabit uzunlukta mesaj paketlerinden oluşuyorsa, o zaman TCP ile sorun yaşarsın, çünkü TCP senin her zaman 1024'ün katı kadar byte almanı sağlamaz. Bu durumda şöyle bir metot kullanman lazım:

TCP soketten okurken recv fonksiyonuna 1024 byte istediğini söylersin ve TCP sana data verdikçe bir buffer'da biriktirirsin. Mesela TCP sana önce 500 byte verdi. Bunu buffer'ına koyar, sonraki recv ile 524 byte istersin. Diyelim TCP sana bu sefer 400 byte verdi. Bunu buffer'ına koyar, sonraki recv ile 124 byte istersin. Bu şekilde buffer'ı doldurduktan sonra mesajı işler, bu döngüyü tekrar başlatırsın.

Eğer mesaj uzunluğu değişken ise, bu sefer, mesaj uzunluğunun da olduğu bir sabit uzunlukta bir header tanımlarsın. Sonra TCP ile bu header'ın tamamını okuyana kadar yukarıdaki döngüyü yaparsın. Header okunduktan sonra mesajın uzunluğu belli olmuştur. Sonraki adım, bu uzunluğu okuyana kadar yukarıdaki döngüyü yaparsın.
 
TCP ile sınırları belirlenmiş mesaj işlemek kolay değil gördüğün gibi. Bir diğer seçenek, UDP protokolü kullanabilirsin. UDP'de her gönderilen mesajın sınırları bellidir ve network sistemi mesajı ya gönderildiği gibi alıcıya ulaştırır, yada mesaj yolda kaybolur. Ama hiçbir zaman alıcıya yarım bir mesaj gitmez. Ama UDP kullandığında artık her mesajın sana ulaştırılacağına, veya ulaştırılamazsa da bir hata verileceğine dair bir garantin kalmıyor. Her mesaj doğru şekilde ulaştı mı, kaybolan mesaj var mı yok mu bunun takibini bizzat senin yapman lazım.
 
Bir üçüncü seçenek de SCTP protokolünü kullanmak. Bunda hem verilerin iletim veya iletilemezse bildirim garantisi var, hem de mesaj sınırları muhafaza ediliyor. Ama bunun da dezavantajı, Windows işletim sistemlerinde SCTP desteği yoktur.
 
Network programlama ile ilgili bilgi düzeyin nedir tam olarak bilmiyorum, o yüzden detaylı anlatıyorum. Anlamadığın yer varsa sorabilirsin.

Network programlama gerektiren bir gerçek hayat uygulaması zordur. Bunlardan öte işin içinde birçok ayrıntı daha var. Eğer bu işi en ince ayrıntısı ile öğrenmek istiyorsan, ingilizceyi çok iyi öğren, sonra da aşağıda bağlantısını verdiğim kitabı satın al. Network programlama ile ilgili en iyi kitaplardan birisidir o. Ben yaklaşık 15 sene önce aldım ve arada bir başvuruyorum.

Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition)

Bu kitap ucuz değil, 65 dolar yeni fiyatı, ama network programlama ile ilgili kendin için yapabileceğin en iyi yatırımlardan birisidir.
 
Ayrıntılı cevap için teşekkürler. TCP ile ilgili söylediğiniz algoritmayı uygulamaya çalışacağım. İngilizce kursuna iki ay önce başladım, öğrenmeye devam ediyorum. Kitabı da sanırım PDF olarak internette bulup indirebilirim.
 
Lütfen kitabın yazarının emeğine saygı göster ve kitabı parasını vererek satın al, yoksa hak yemiş olursun ve ondan da sana fayda gelmez.

Biraz para biriktir veya ailenden destek al, sonra da amazon'dan direkt sipariş et. Parasını vererek aldığın için, o kitabın her sayfasını, her dip notunu, içindekiler kısmını, her şeyini okuyacaksın, yani o kitaptan tam olarak yararlanmış olacaksın. Ama internetten bedava bulduğun o PDF'in senin gözünde bir değeri olmayacak ve onu biraz okuyup bir kenara atacaksın. Birisinin hakkını yiyerek yapılan işin de bir bereketi olmaz.
 
Bahsettiğiniz data biriktirme olayını denedim, ama bir türlü çalışır hale getiremedim. Muhtemelen program ile ilgili bir sorun var. Artık bu şekilde hocaya göstereceğim. Eğer hocaya gösterdiğim sırada gene satırlar bölünürse, bunun teknik açıklamasını sizin belirttiğiniz gibi hocaya anlatacağım.

Kitabı satın alma konusunda haklısınız. Çok fazla alıştık herşeyin korsanına. O kitabı satın alacağım inş.
 
Eğer telnet ile denemeye devam ettiysen, yukarıda bahsettiğim algoritma işe yaramaz zaten. Bu algoritmada, ya gelen her mesaj sabit uzunlukta olacak, yada değişken uzunluk olacak, ama başında sabit uzunlukta bir header olacak. telnet ile sen sabit uzunlukta mesaj göndermiyorsun, telnet'in kendisi de bahsedilen header'i eklemiyor, o yüzden telnet ile bu iş olmaz. Kendin bir client yazacaksın ve ondan göndereceksin mesaj (ya sabit uzunluk veya header'lı).
 
Hocaya programı bu şekilde gösterdim ve yarım paket olayı da denemelerde ortaya çıktı.Nedenini anlatmaya çalıştım ama hoca bunun benim programdaki bir bugdan kaynaklandığını söyledi Ş:confused:
 
Bir dakika, eğer hoca "TCP'de böyle yarım paket gelemez, yarım paket senin programdaki bug'dan kaynaklanıyor" diyorsa, kusura bakmasın, ama bu yanlış. Ama hocanın dediği "böyle ödev yapılmaz, paketler yarım gelmesin, tam gelsin, gelmediğine göre senin program hatalı" diyorsa, o zaman doğru söylüyor :) Senin program TCP kullanıyor ama TCP'nin limitasyonlarına aldırış etmediği için de yarım paket olayı meydana geliyor.

Burada önemli olan SENİN işin aslını anlaman. Hocayı bu konuda ikna etmişsin etmemişsin önemli değil. İlla hoca "yarım paket istemiyorum" diyorsa, kodu SCTP kullanacak şekilde değiştir ve programın demosunu Linux altında yap. Yarım paket olayı olmayacaktır, hoca da memnun olacak, sen de notunu kapacaksın :)
 

Çevrimiçi personel

Forum istatistikleri

Konular
5,786
Mesajlar
98,960
Üyeler
2,464
Son üye
s4met

Son kaynaklar

Son profil mesajları

cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Kesici/Spindle hızı hesaplamak için SpreadSheet UDF'leri kullanın, hesap makinesi çok eski kalan bir yöntem :)
Dr. Bülent Başaran,
Elektrik ve Elektronik Mühendisi
Yonga Tasarım Özdevinimcisi
Üç güzel "çocuk" babası
Ortahisar/Ürgüp/Konya/Ankara/Pittsburgh/San Francisco/Atlanta/Alaçatı/Taşucu...

Back
Top