linux - 内核循环缓冲实现seek功能相关的问题
PHP中文网
PHP中文网 2017-04-17 11:23:24
[Linux讨论组]

对于网络数据的发送,一次操作返回值可能小于所指定输出的字节数。对于从客户端发送一个文件到服务器端的例子,可以从两个方面进行一些处理:
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)的各种可能情况;

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

PHP中文网
PHP中文网

认证0级讲师

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号