0
点赞
收藏
分享

微信扫一扫

socket不完整传输的后续处理

  • 英文小册原文地址: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);
}

当部分数据包到达时,接收器端会发生什么?

如果数据包是可变长度的,接收方如何知道一个数据包何时结束,另一个何时开始?

现实世界的情景百出往往最让我们头疼。你必须得使用封装(忘记这个概念的话点我)来解决这个问题喽。

下文见!

举报

相关推荐

0 条评论