9

我需要将数据发送到套接字,基本上是传输文件,

根据 send() 函数文档,它说,

If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter. Otherwise, a value of SOCKET_ERROR is returned,

我担心的是,返回值可能小于请求值。因为我正在读取文件并写入套接字,因为它可能不会发送所有字节,所以我想如果没有发送完整的缓冲区,我将不得不重试?在这种情况下,我想我必须以某种方式将同一缓冲区上的指针通过读取的字节提前并再次发送?

我只想知道是不是这样?还是有一个非常聪明的方法,以便发送所有请求的数据,而我不必担心什么时候没有发送所有数据?

谢谢,

4

3 回答 3

11

是的,您必须推进缓冲区指针并重复send调用,直到整个缓冲区被消耗或出现硬错误。标准的成语看起来像这样:

int
send_all(int socket, const void *buffer, size_t length, int flags)
{
    ssize_t n;
    const char *p = buffer;
    while (length > 0)
    {
        n = send(socket, p, length, flags);
        if (n <= 0)
            return -1;
        p += n;
        length -= n;
    }
    return 0;
}

请注意,如果您正在发送边界很重要的数据报(例如 UDP),则不能使用此技术;您必须将短发送视为失败。

于 2013-01-06T16:36:29.050 回答
6

您可以尝试以下方法:

int ret, bytes = 0;
while (bytes < buflen) {
    ret = send(sock_fd, buf+bytes, buflen-bytes, flags);
    //check for errors
    if (ret == -1) {
        // handle error
    }
    bytes+=ret;
}
于 2013-01-06T16:36:44.227 回答
3

是的,您确实必须担心send(或write等等)返回的值。没有非常聪明的解决方法,但是优秀的 Richard Stevens 编写了一些函数,即readnwriten

informit 上的这篇文章似乎有这些功能的一个版本。

于 2013-01-06T16:34:17.443 回答