内核循环缓冲实现seek功能相关的问题

发布于 2022-08-26 15:29:15 字数 1337 浏览 18 评论 0

对于网络数据的发送,一次操作返回值可能小于所指定输出的字节数。对于从客户端发送一个文件到服务器端的例子,可以从两个方面进行一些处理:
1、多次发送没有发送了的数据

ssize_t sendn(int sock_fd, const void *ptr, size_t n)
{
    size_t nleft = n;
    ssize_t nwritten;

    while(nleft > 0) {
        if((nwritten = send(sock_fd, ptr, nleft, 0)) < 0) {
            if(nleft == n)
                return -1;
            else
                break;
        } else if(nwritten == 0) 
            break;

        nleft -= nwritten;
        ptr += nwritten;
    }

    return (n - nleft);
}

2、使用lseek指定到文件正确的读写位置

while(1) {
    bzero(buffer, BUFFER_SIZE);

    size = read(file_fd, buffer, BUFFER_SIZE);
    if(size <= 0)
        break;

    if((nsendsize = sendn(sock_fd, buffer, size)) < 0) {
        perror("sendn error!\n");
        lseek(file_fd, -size, SEEK_CUR);
        return -1;
    }

    if(nsendsize < size)
        lseek(file_fd, nsendsize - size, SEEK_CUR);
}

如果读取不是文件,而是一个循环缓冲区(例如内核中的kfifo,请参考源码了解),那么第1步的处理对于它来说同样有效,第2步的处理则无效。那么就需要实现一个类似lseek的功能,感觉挺复杂的,需要考虑的东西比较多。目前主要考虑到以下一些问题:
a、(in - out)的差值会大于size(以上问题的情况,offset小于0);
b、in和out两者都溢出或则只有in溢出后的偏移处理(关于溢出的情况,可以参考这个问题);
c、(out = out + offset)的各种可能情况;

各位,对该问题有什么建议或者想法?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文