macOS sendfile 将 errno 设置为 45

macOS sendfile sets errno to 45

我正在尝试使用 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 时,客户端收到“连接被对等方关闭”的消息;

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

你把论点搞反了。根据 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);
The sendfile() system call sends a regular file specified by descriptor fd out a stream socket specified by descriptor s.

因此您的代码并未尝试通过套接字发送文件。它试图通过文件发送套接字,这是没有意义的。更改顺序。