内核循环缓冲实现seek功能相关的问题
对于网络数据的发送,一次操作返回值可能小于所指定输出的字节数。对于从客户端发送一个文件到服务器端的例子,可以从两个方面进行一些处理:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论