浏览器访问html页面会下载它的问题?
问题描述:我用C++写了一个简单的Web服务器,但是,在用浏览器访问HTML页面的时候,它会把这个文件的相关内容下载下来。我用telnet来测试端口的时候,是可以按照我代码的意思看到想要的效果。不知道问题可能是出在哪里?
代码如下:
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
const int BUFFSIZE = 1024;
const int MAXLINK = 10; // 未经过处理的连接请求队列可以容纳的最大数目
const int DEFAULT_PORT = 8080;
int makesure_write(int connect_fd, void* buff, int n) {
int remain_num = n;
int success_write_num = 0;
char* buff_current_postition = (char*)buff;
while (remain_num > 0) {
success_write_num = write(connect_fd, buff_current_postition, remain_num);
remain_num -= success_write_num;
buff_current_postition += success_write_num;
}
return n - remain_num;
}
void get_filetype(const char* file_name, char* file_type) {
if (strstr(file_name, ".html"))
strcpy(file_type, "text/html");
else if (strstr(file_name, ".gif"))
strcpy(file_type, "image/gif");
else if (strstr(file_name, ".png"))
strcpy(file_type, "image/png");
else if (strstr(file_name, ".jpg"))
strcpy(file_type, "image/jpeg");
else
strcpy(file_type, "text/plain");
}
int get_file_size(char* file_name) {
FILE* fp = fopen(file_name, "r");
if (!fp) {
return -1;
}
fseek(fp, 0L, SEEK_END); // 移动文件指针到文件的末尾
int size = ftell(fp); // 获得目前的文件的访问位置,从而间接获得文件的大小
fclose(fp);
return size;
}
char* get_file_name (char* buff) {
char* file_name = buff + 5;
char *space = strchr(file_name, ' ');
*space = '\0';
return file_name;
}
void deal_get_http(int connect_fd, char* request_header) {
char* file_name = get_file_name(request_header);
int file_size = get_file_size(file_name);
char file_type[BUFFSIZE];
get_filetype(file_name, file_type);
int fd = open(file_name, O_RDONLY);
void* file_in_mem_addr = mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
char buff[BUFFSIZE];
sprintf(buff, "HTTP/1.0 200 OK\r\n");
sprintf(buff, "%sServer: HHTWS Web Server\r\n", buff);
sprintf(buff, "%sContent-length: %d\r\n", buff, file_size);
sprintf(buff, "%sContent-type: %s\r\n\r\n", buff, file_type);
makesure_write(connect_fd, buff, strlen(buff));
makesure_write(connect_fd, file_in_mem_addr, file_size);
munmap(file_in_mem_addr, file_size);
}
bool is_get_http(char* buff) {
if (!strncmp(buff, "GET", 3)) { // 如果是GET请求
return true;
}
else {
return false;
}
}
int main(int argc, char const *argv[])
{
int socket_fd, connect_fd;
struct sockaddr_in servaddr;
char buff[BUFFSIZE];
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
cout<<"create socket error"<<endl;
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // IP必须是网络字节序,INADDR_ANY是绑定本机上所有IP
servaddr.sin_port = htons(DEFAULT_PORT); // 端口号必须是网络字节序
if (bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
cout<<"bind error"<<endl;
return -1;
}
if (listen(socket_fd, MAXLINK) == -1) {
cout<<"listen error"<<endl;
}
connect_fd = accept(socket_fd, (struct sockaddr*)NULL, NULL);
if (connect_fd == -1) {
cout<<"accept error"<<endl;
}
else {
cout<<"连接成功"<<endl;
}
memset(buff, '\0', sizeof(buff));
recv(connect_fd, buff, BUFFSIZE - 1, 0); // 把请求头(或发送的消息)写入buff中
send(connect_fd, buff, BUFFSIZE - 1, 0); // 向客户端发送消息(发送buff中的内容)
if (is_get_http(buff)) {
cout<<"it is get http"<<endl;
deal_get_http(connect_fd, buff);
}
close(connect_fd);
close(socket_fd);
return 0;
}
以下是测试的一些截图
虚拟机里面的浏览器访问结果如下:
也就是说它把文件下载下来了。
然后我把我的代码放到阿里云上面跑,然后通过浏览器访问,得到如下结果:
从这张图片里可以看出,响应头并没有发送给浏览器。而这样的结果似乎和在虚拟机下面访问有些不同。在虚拟机里的浏览器是可以获得响应头的。
下面是我通过telnet来测试端口的结果:
服务器部分:
客户端部分:
从这个结果看下来,感觉返回的信息是写对了。问题好像是出在如何让浏览器来接收这个响应?
我感觉是不是返回响应头给客户端的时候出了问题?
希望前辈可以解答
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在本地测试了一下,完全没问题,浏览器打印出了I am index.
你其实不用写这么麻烦,你可以去看看
CGI
的功能,就是你想要的,你不需要按照HTTP协议自己全部重新实现,把对接HTTP协议的部分交给CGI
就可以了大哥 你用文件浏览器方式打开 肯定是下载 或者打开源码啊,得部署到服务器 ,比如PHPstudy