向客户端发送文件内容res.end()位置问题

今天踩了一个小坑

今天我要将一个html页面的内容发到客户端去,我觉得这么写完全没问题啊,怎么就是没数据返回呢?

http.createServer((req,res) => {
	fs.readFile('./login.html',(err, data) => {
		res.write(data)	
	})
	res.end()
})

我试了好多遍,吧res.end()res.write()换了好多个地方,就是不知道为什么不行,现在明白了,把我的理解写一下

  1. fs.readFile()是一个异步读取文件的方法,当第一个参数是一个路径时,其底层其实是调用了fs.open()fs.read()fs.close()这些方法的,所以说当函数调用结束,数据流就被关闭了

  2. response.write()的一个小特性

When write function is called with empty string or buffer, it does nothing and waits for more input.

意思是说,“当使用空字符串或缓冲区调用write函数时,它什么也不做,而是等待更多的输入。 ”

http.createServer((req,res) => {
	fs.readFile('./login.html',(err, data) => {
		res.write(data)	// 这里的data在了缓冲区内,所以实际上它啥也不干
	})
	// fs.readFile() 方法调用完成,读取流被关闭了,缓冲区被清空了
	
	res.end()	// 之前的res.write()根本没点屁用,所以这里一点数据都返回不了
})

所以就只能这样写

http.createServer((req,res) => {
	fs.readFile('./login.html',(err, data) => {
		res.write(data)
		res.end()	// 这样写在数据流未关闭时将数据完整发送出去了
	})
})

结论:在fs.readFile 的 回调函数中使用 red.write()时,必须在 fs.readFile的回调函数中使用res.end()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的示例代码,可以发送指定文件到服务器。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define BUF_SIZE 1024 int main(int argc, char *argv[]) { int sock; struct sockaddr_in serv_addr; char filename[256]; char buf[BUF_SIZE]; int file_size, nread, nsend, total_send = 0; int fd; if (argc != 3) { printf("Usage: %s <server_ip> <port>\n", argv[0]); exit(1); } // 创建套接字 sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { perror("socket"); exit(1); } // 初始化服务器地址结构体 memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(argv[1]); serv_addr.sin_port = htons(atoi(argv[2])); // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { perror("connect"); exit(1); } // 获取要发送文件名 printf("Enter filename: "); fgets(filename, sizeof(filename), stdin); filename[strlen(filename) - 1] = '\0'; // 去除换行符 // 打开文件 fd = open(filename, O_RDONLY); if (fd == -1) { perror("open"); exit(1); } // 获取文件大小 file_size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); // 发送文件名和文件大小 sprintf(buf, "%s %d", filename, file_size); if (send(sock, buf, strlen(buf), 0) == -1) { perror("send"); exit(1); } // 循环读取文件发送 while ((nread = read(fd, buf, BUF_SIZE)) > 0) { nsend = send(sock, buf, nread, 0); if (nsend == -1) { perror("send"); exit(1); } total_send += nsend; } if (nread == -1) { perror("read"); exit(1); } printf("Sent %d bytes.\n", total_send); // 关闭套接字和文件 close(fd); close(sock); return 0; } ``` 注意事项: 1. 在发送文件之前,需要先向服务器发送文件名和文件大小,以便服务器知道接收的文件信息。 2. 在读取文件时,需要使用循环读取,直到文件全部读取完毕。 3. 在发送文件时,需要使用循环发送,直到文件全部发送完毕。记得记录已经发送的字节数,以便统计发送文件大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值