是否可以直接从文件写入套接字?
Is it possible to write directly from file to the socket?
我对 Apache 或 Nginx 等 Web 服务器的基本原理很感兴趣,所以现在我正在开发自己的服务器。
当我的服务器收到请求时,它正在搜索一个文件(例如 index.html
),如果它存在 - 将所有内容读取到缓冲区(content
)并将其写入套接字后。这是一个简化的代码:
int return_file(char* content, char* fullPath) {
file = open(fullPath, O_RDONLY);
if (file > 0) { // File was found, OK
while ((nread = read(file, content, 2048)) > 0) {}
close(file);
return 200;
}
}
问题很简单:是否可以避免使用缓冲区并将文件内容直接写入套接字?
感谢任何提示:)
你能做的就是将你立即阅读的“chunk”写给客户端。
为了写入内容,您必须读取它,所以您无法避免这种情况,但您可以使用较小的缓冲区,并在读取内容时写入内容,从而无需将整个文件读入内存。
例如,您可以
unsigned char byte;
// FIXME: store the return value to allow
// choosing the right action on error.
//
// Note that `0' is not really an error.
while (read(file, &byte, 1) > 0) {
if (write(client, &byte, 1) <= 0) {
// Handle error.
}
}
但是,unsigned char byte;
可能是 unsigned char byte[A_REASONABLE_BUFFER_SIZE];
哪个更好,而且您不需要将所有内容都存储在内存中。
}
不,不是。必须有用于 reading/writing 数据的中间存储。
有一种边缘情况:当您使用内存映射文件时,映射文件的区域可用于写入套接字。但在内部,系统无论如何都会执行读入内存缓冲区的操作。
没有可以直接从文件写入套接字的标准化系统调用。
不过,有些操作系统确实提供了这样的调用。例如,FreeBSD 和 Linux 都实现了一个名为 sendfile
的系统调用,但两个系统的具体细节有所不同。 (在这两种情况下,您都需要文件的底层文件描述符,而不是 FILE*
指针,尽管在这两种平台上您都可以使用 fileno()
从 FILE*
中提取 fd。)
更多信息:
我对 Apache 或 Nginx 等 Web 服务器的基本原理很感兴趣,所以现在我正在开发自己的服务器。
当我的服务器收到请求时,它正在搜索一个文件(例如 index.html
),如果它存在 - 将所有内容读取到缓冲区(content
)并将其写入套接字后。这是一个简化的代码:
int return_file(char* content, char* fullPath) {
file = open(fullPath, O_RDONLY);
if (file > 0) { // File was found, OK
while ((nread = read(file, content, 2048)) > 0) {}
close(file);
return 200;
}
}
问题很简单:是否可以避免使用缓冲区并将文件内容直接写入套接字?
感谢任何提示:)
你能做的就是将你立即阅读的“chunk”写给客户端。
为了写入内容,您必须读取它,所以您无法避免这种情况,但您可以使用较小的缓冲区,并在读取内容时写入内容,从而无需将整个文件读入内存。
例如,您可以
unsigned char byte;
// FIXME: store the return value to allow
// choosing the right action on error.
//
// Note that `0' is not really an error.
while (read(file, &byte, 1) > 0) {
if (write(client, &byte, 1) <= 0) {
// Handle error.
}
}
但是,unsigned char byte;
可能是 unsigned char byte[A_REASONABLE_BUFFER_SIZE];
哪个更好,而且您不需要将所有内容都存储在内存中。
}
不,不是。必须有用于 reading/writing 数据的中间存储。
有一种边缘情况:当您使用内存映射文件时,映射文件的区域可用于写入套接字。但在内部,系统无论如何都会执行读入内存缓冲区的操作。
没有可以直接从文件写入套接字的标准化系统调用。
不过,有些操作系统确实提供了这样的调用。例如,FreeBSD 和 Linux 都实现了一个名为 sendfile
的系统调用,但两个系统的具体细节有所不同。 (在这两种情况下,您都需要文件的底层文件描述符,而不是 FILE*
指针,尽管在这两种平台上您都可以使用 fileno()
从 FILE*
中提取 fd。)
更多信息: