- 英文小冊原文位址:beej.us/guide/bgnet…
- 作者:Beej
- 中文翻譯位址:www.chanmufeng.com/posts/netwo…
回想一下之前我講過的send()函數,我當時說過,
send()
可能不會一下子把你所有的資料都發送出去,比如你想放一個長度為
512
位元組的字元串,
send()
的傳回值卻是
412
。你可能不禁會問到,剩下的
100
位元組怎麼辦?
其實這
100
位元組仍然在你小得可憐的緩沖區(buffer)中,等着你把他們發送出去呢!畢竟事事無法如你所願,核心也會有自己的小脾氣,有時就是不想把你的資料一下子發送出去,你還得自己動手把剩下的資料發送出去。
你可以這麼寫:
#include <sys/types.h>
#include <sys/socket.h>
int sendall(int s, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;
while(total < *len) {
n = send(s, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
上例中,
s
是你想發送資料的
socket
,
buf
是儲存資料的緩沖區(buffer),
len
指向一個
int
類型的變量,這個變量記錄了緩沖區剩餘資料的大小。
send()
異常時會傳回
-1
,并且最終實際發送的位元組數量儲存在了
len
變量中。
sendall()
會竭盡全力發送你所有的資料,除非發生了錯誤會導緻立即傳回,否則
len
的值一定就是你想發送的資料的長度。
為了完整性,給一個使用
sendall()
函數的例子:
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);
}
當部分資料包到達時,接收器端會發生什麼?