Hatırlarsanız
send() ve recv() -- Konuş Benimle Bebeğim! bölümünde
send()
işlevinin sizin istediğiniz kadar veriyi bir anda gönderemeyebileceğinden
bahsetmiştim. Tam olarak böyle yani siz ondan 512 byte göndermesini
istersiniz ama o sadece 412 tanesini yollar. Peki geriye kalan 100
bayta ne oldu?
Bu veriler hala bizim küçük tampon bölgemizde gönderilmeyi bekliyorlar.
Kontrolünüz dışındaki bir takım sebeplerden ötürü işletim sistemi
çekirdeği mevcut veriyi bir seferde göndermemeye karar verdi ve iş
başa düştü.
Sorunu halletmek için şöyle bir işlev kullanabilirsiniz:
#include <sys/types.h>
#include <sys/socket.h>
int sendall(int s, char *buf, int *len)
{
int total = 0; // gönderdigimiz byte miktari
int bytesleft = *len; // eksik kalan byte miktari
int n;
while(total < *len) {
n = send(s, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total; // gönderilen toplam bayt miktarı
return n==-1?-1:0; // sorun varsa -1, işlem tamamsa 0 döner
}
Bu örnekte, s üzerinden veriyi göndermek
istediğimiz soketi, buf veriyi barındıran bellek
bölgesini (buffer) ve len de tampondaki byte
sayısını gösteren sayıya işaret eden int türünde
bir göstergedir.
Hata durumunda işlev -1 değerini döndürür (ve
errno hata değişkeni de send()
işlevi sayesinde gerekli hata kodunu barındırır.) Ayrıca gönderilebilmiş
olan byte sayısı da len parametresinden depolanır.
Bu sayı sizin göndermek istediğiniz sayıya eşit olacaktır (hata oluşması
durumu haricinde). sendall() işlevi verinin
tamamını yollamak için elinden geleni yapacaktır ancak bir hata ile
karşılaşırsa size geri dönecektir.
Hemen bir örnek verelim:
char buf[10] = "Beej!";
int len;
len = strlen(buf);
if (sendall(s, buf, &len) == -1) {
perror("sendall");
printf("We only sent %d bytes because of the error!\n", len);
}
Peki ya verinin sadece bir kısmı diğer tarafa erişebildiğinde diğer
tarafta ne olup biter? Eğer gelen paketlerin boyu değişken ise bunları
alan taraf bir paketin ne zaman bittiğini, diğerinin ne zaman
başladığını nasıl anlar? Evet, gerçek dünya senaryoları insanları biraz
düşünmeye zorlar. Büyük ihtimalle yukarıdaki problemlerle başa
çıkabilmek için yapmanız gereken veriyi paketlemek (encapsulate)
olacaktır (
veri paketleme bölümünü
hatırladınız mı?) Ayrıntılar için okumaya devam edin!