> For the complete documentation index, see [llms.txt](https://beej-zhcn.netdpi.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://beej-zhcn.netdpi.net/advanced_tech/bu_wan_zheng_chuan_song_de_hou_xu_chu_li.md).

# 7.3. 不完整传送的後续处理

还记得前面的 **send()** 章节吗？当时我不是提过 **send()** 可能不会将你所要求的数据全部送出吗？也就是说，虽然你想要送出 512 bytes，但是 send() 只送出 412 bytes。那剩下的 100 个 bytes 到哪去了呢？\
\
好的，其实它们还在你的缓冲区里。因为环境不是你能控制的，kernel 会决定要不要用一个 chunk 将全部的数据送出，而现在，我的朋友，你可以决定要如何处理缓冲区中剩下的数据。\
\
你可以写一个像这样的函数：<br>

```c
#include <sys/types.h>
#include <sys/socket.h>

int sendall(int s, char *buf, int *len)
{
  int total = 0; // 我们已经送出多少 bytes 的数据
  int bytesleft = *len; // 我们还有多少数据要送
  int n;

  while(total < *len) {
    n = send(s, buf+total, bytesleft, 0);
    if (n == -1) { break; }
    total += n;
    bytesleft -= n;
  }

  *len = total; // 返回实际上送出的数据量

  return n==-1?-1:0; // 失败时返回 -1丶成功时返回 0
}
```

在这个例子里，*s* 是你想要传送数据的 socket，*buf* 是储存数据的缓冲区，而 *len* 是一个指针，指向一个 int 型别的变数，记录了缓冲区中的数据数量。\
\
函数在错误时返回 -1［而 *errno* 仍然从调用 **send()** 设置］。还有，实际送出的数据数量会在 *len* 中回传，除非有错误发生，不然这会跟你所要求要传送的数据量相同。**sendall()** 会尽力将数据送出，不过如果有错误发生时，它就会立刻回传给你。\
\
为了完整性，这边有一个调用函数的示例：<br>

```c
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);
}
```

当数据包的一部分抵达接收端（receiver end）时会发生什麽事情呢？如果数据包的长度是会变动的（variable），接收端要如何知道另一端的数据包何时开始与结束呢？\
\
是的，你或许必须封装（encapsulate）［还记得数据封装（data encapsulation）章节的开头那边吗？那边有详细说明］。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://beej-zhcn.netdpi.net/advanced_tech/bu_wan_zheng_chuan_song_de_hou_xu_chu_li.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
