加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

udp – Linux splice()返回EINVAL(“无效参数”)

发布时间:2020-12-14 01:25:16 所属栏目:Linux 来源:网络整理
导读:我正在尝试使用splice( man 2 splice)将数据从UDP套接字直接复制到文件.不幸的是,第一次调用splice()会返回EINVAL. 手册页指出: EINVAL Target file system doesn't support splicing; target file is opened in append mode; neither of the descriptors r
我正在尝试使用splice( man 2 splice)将数据从UDP套接字直接复制到文件.不幸的是,第一次调用splice()会返回EINVAL.

手册页指出:

EINVAL Target file system doesn't support splicing; target file is opened in
       append mode; neither of the descriptors refers to a pipe; or offset
       given for nonseekable device.

但是,我相信这些条件都不适用.我正在使用Fedora 15(内核2.6.40-4),所以我相信所有文件系统都支持splice().目标文件在第一次调用splice时应该是无关紧要的,但为了完整性我将通过open(路径,O_CREAT | O_WRONLY | O_TRUNC,S_IRUSR | S_IWUSR)打开它.两个调用都使用管道,除了NULL之外,两个调用都不使用偏移量.

这是我的示例代码:

int sz = splice(sock_fd,mPipeFds[1],8192,SPLICE_F_MORE);
if (-1 == sz)
{
int err = errno;
LOG4CXX_ERROR(spLogger,"splice from: " << strerror(err));
return 0;
}

sz = splice(mPipeFds[0],file_fd,sz,"splice to: " << strerror(err));
}

return 0;

sock_fd由以下psuedocode初始化:

int sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,&one,sizeof(one));
fcntl(sock_fd,F_SETFL,flags | O_NONBLOCK);
bind(sock_fd,...);

可能相关的是这段代码片段在libevent循环中运行. libevent正在使用epoll()来确定UDP套接字是否很热.

解决方法

找到我的答案. tl; dr – 入站端不支持UDP.

经过足够的谷歌搜索后,我偶然发现了一个forum discussion和一些test code,它打印出一个输入/输出fd类型的表格及其支持:

$./a.out 
inout     pipe    reg     chr     unix    tcp    udp
pipe       yes     yes     yes     yes     yes    yes
reg        yes     no      no      no      no     no
chr        yes     no      no      no      no     no
unix       no      no      no      no      no     no
tcp        yes     no      no      no      no     no
udp        no      no      no      no      no     no

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读