【问题标题】:macOS sendfile sets errno to 45macOS sendfile 将 errno 设置为 45
【发布时间】:2021-12-27 14:48:34
【问题描述】:

我正在尝试使用sendfile() 函数在 macOS 上编写一个简单的类似 FTP 的客户端-服务器网络程序。看完Apple's developer Manual on this topic后,很遗憾我仍然无法使用它。

代码

// creation of fd
int fd = open("file_path", O_RDONLY);
off_t len = 0;

// the creation of sockets used in sendfile
getaddrinfo(NULL, port, &hints, &servinfo);
// p is iterating through servinfo (p=p->ai_next)
sockfd= socket(p->ai_family, p->ai_socktype, p->ai_protocol);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
bind(sockfd, p->ai_addr, p->ai_addrlen);
listen(sockfd, BACKLOG);    //BACKLOG is a macro configuring pending connections

new_sockfd = accept(sockfd, (struct sockaddr*)&clients_addr, &sin_size);

// sendfile
if(sendfile(new_sockfd, fd, 0, &len, NULL, 0)==-1){
    fprintf(stderr, "server sendfile errno: %d", errno);    
    // sorry I know this is not the best way to interpret the errno
}

当errno代码设置为45时,客户端收到“connection closed by peer”的消息;

我已经使用read()检查了文件描述符fd并打印了它,它工作正常;

【问题讨论】:

  • Errno 45 是 ENOTSUPP,Apple 的文档说这意味着“描述符 fd 的文件系统不支持 sendfile()。”所以你的a_working_socket 有问题,但我们不知道是什么问题,因为你没有显示任何代码或告诉我们究竟是什么。
  • printf("%s\n", strerror(45)); 产生“不支持操作”,在 sendto() 手册页上列为“描述符 fd 的文件系统不支持 sendfile()”
  • @JohnZwinck 谢谢你的信息!我添加了更多关于sendfile() 中使用的套接字的信息。我希望它可以帮助识别我的错误;

标签: macos sockets network-programming


【解决方案1】:

你的论点倒退了。根据the documentation,错误代码ENOTSUP(我假设它是“不支持操作”——感谢Jeremy Friesner 查找它——你应该打印strerror(errno),因为它很有用)意味着fd 不是一个常规文件。

fd 是第一个参数。

int sendfile(int fd, int s, off_t offset, off_t *len, struct sf_hdtr *hdtr, int flags);
sendfile() 系统调用将描述符 fd 指定的常规文件发送到描述符 s 指定的流套接字。

所以您的代码不会尝试通过套接字发送文件。它试图通过文件发送套接字,这没有意义。更改顺序。

【讨论】:

    猜你喜欢
    • 2017-05-29
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 2010-10-18
    • 2015-06-05
    • 2017-08-29
    相关资源
    最近更新 更多