《简单的http网站的构建》

【一】什么是协议

通过udp和tcp协议大家知道,无论是以数据报还是字节流的方式去把信息传送出去,都需要将我们所有的信息转化为字符串的形式进行发送,这叫序列化,在另外一头将字符串转化为我们所需要的信息,这是反序列化。但是如何序列化及如何反序列化,这个约定就被称为应用层协议

【二】HTTP协议

虽然我们说,应用层协议是程序员自己定制的,但是作为一个cv工程师,能cv绝不自己手写。所以总有大佬带头定义了一套现成的非常好用的应用层协议,比如http(超文本传输协议)就是其中之一。

tips:超文本传输协议,顾名思义就是不仅限于文本的传输协议,还能传输音频,图片等等,是不是有的人觉得http这玩意看着有点眼熟,你没发现你的网址前缀就是这玩意吗?其实也没必要把这个玩意看成啥高大上的东西,这东西只是一个协议,协议只是一个约定,也就是意味着你底层还是需要将其转化为字符串进行传输,只不过是通过固定的格式进行传输

【三】HTTP的状态码

类别原因短语
1xxInformational(信息状态码)接收的请求正在处理
2xxSuccess(成功状态码)请求正常处理完毕
3xxRedirection(重定向状态码)需要进行附加操作以完成请求
4xxClient Error(客户端错误状态码)服务器无法处理请求
5xxServer Error(服务器错误状态码)服务器请求出错

tips:关于HTTP状态码一些不得不说的小故事

同学们访问网页的时候,最多出现的还是404,也就是服务器无法处理请求,而不是5xx,这是为啥呢?你想想4xx是客户端错误码,客户端是使用的人的问题,而5xx是服务端,也就是服务器出了问题,抱着打死不认错的态度,当然不会说这是我服务器的错误了对吧,其实底层还有更胜一层的原因,总有一些黑客喜欢干一些破坏团结的事情,当你使用一些特殊的访问导致的服务器出错,那那些人就知道你的服务器的弱点,从而进行攻击,但是你如果返回的是4xx他们可能就不会再这个报错上多花心思了

【四】HTTP的方法

方法说明支持的HTTP的协议版本
GET获取资源1.0/1.1
POST传输实体主体1.0/1.1
PUT传输文件1.0/1.1
HEAD获得报文首部1.0/1.1
DELETE删除文件1.0/1.1
OPTIONS询问支持方法1.1
TRACE追钟路径1.1
CONNECT要求用隧道协议链接代理1.1
LINK建立和资源之间的关系1.0
UNLINE断开连接关系1.0

其实上面列举了这么多,最常用的其实还是get和post的方法,其他的基本上是用不到的

【五】HTTP常见的header

content-type数据类型(text/html)
content-lengthBody的长度
host客户端告诉服务器,所请求的资源是在哪个端口上
user-Agent声明用户的操作系统和浏览器版本信息
refer当前页面是从哪个页面跳转过来的
location搭配3xx状态码使用,告诉客户端接下来咱们去哪里
cookie在客户端存储少量信息,通常用于实现会话功能

【六】最简单的HTTP服务器

实现一个最简单的HTTP服务器,只在网页上输入“hello world”,只要我们按照HTTP协议构造数据,就很容易做到。、

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void Usage() {
 printf("usage: ./server [ip] [port]\n");
}
int main(int argc, char* argv[]) {
 if (argc != 3) {
 Usage();
 return 1
 }
 int fd = socket(AF_INET, SOCK_STREAM, 0);//创建网络套接字
 if (fd < 0) {
 perror("socket");
 return 1;
 }
 struct sockaddr_in addr;
 addr.sin_family = AF_INET;
 addr.sin_addr.s_addr = inet_addr(argv[1]);
 addr.sin_port = htons(atoi(argv[2]));
 int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));//bind相关信息
 if (ret < 0) {
 perror("bind");
 return 1;
 }
 ret = listen(fd, 10);//设计监听状态
 if (ret < 0) {
 perror("listen");
 return 1;
 } 
 for (;;) {
 struct sockaddr_in client_addr;
 socklen_t len;
 int client_fd = accept(fd, (struct sockaddr*)&client_addr, &len);//接受服务端口
 if (client_fd < 0) {
 perror("accept");
 continue;
 }
 char input_buf[1024 * 10] = {0}; // 用一个足够大的缓冲区直接把数据读完.
 ssize_t read_size = read(client_fd, input_buf, sizeof(input_buf) - 1);//读取请求
 if (read_size < 0) {
 return 1;
 }
 printf("[Request] %s", input_buf);
 char buf[1024] = {0};
 const char* hello = "<h1>hello world</h1>";
 sprintf(buf, "HTTP/1.0 200 OK\nContent-Length:%lu\n\n%s", strlen(hello), hello);//写入数据
 write(client_fd, buf, strlen(buf));
 }
 return 0;
}

1.打开网络套接字,这一步可以理解为打开网卡,之后的链接都是从网卡中读取的

2.将网卡信息和自己的主机端口号和ip地址进行绑定

3.设置网络套接字为监听状态,监听一切访问这个ip地址的信息

4.接受信息和写入信息

tips:其中写入的信息是必须按照http协议进行构造,否则浏览器无法进行解析,其中网站用的语言为html,这个语言还是比较好学的,有想法的同学还是可以学习。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值