HTTP 协议一般指 HTTP(超文本传输协议)。
超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议,是因特网上应用最为广泛的一种网络传输协议,所有的万维网文件都必须遵守这个标准。
HTTP是一个基于TCP/IP通信协议来传递数据(我们要传输的数据是HTTP报文,报文是通过TCP协议来传输的)
下面来看这么一个题,当你在浏览器输入www.baidu.com,按下回车之后会发生哪些事情?
当你在浏览器输入www.baidu.com百度的域名之后,先由DNS查询到百度服务器的某一IP,然后由浏览器与服务器三次握手建立连接,然后浏览器发送HTTP请求报文,服务器回复HTTP应答报文(应用层是HTTP协议,但是传输层还是调用的TCP协议)
下面来看一下关于HTTP的一些方法和HTTP状态码和状态信息及含义:-------截图取自《Linux高性能服务器编程》
![](https://img-blog.csdnimg.cn/ed7e9ff1d44242dea75d84301e8d9859.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56We5Y6o5bCP56aP6LS177yB,size_20,color_FFFFFF,t_70,g_se,x_16)
我们在前面的那个图里面写到了HTTP的请求报文和HTTP的应答报文,那么这个HTTP报文是啥呢?
HTTP请求报文:
HTTP应答报文:有个东西得说明一下 无论是应答报文还是请求报文最后都有个\r\n (最后的空行中也有一个\r\n)
![](https://img-blog.csdnimg.cn/55c8ffe41156474087fef14acdd2c7e8.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56We5Y6o5bCP56aP6LS177yB,size_20,color_FFFFFF,t_70,g_se,x_16)
这些HTTP报文的格式得我们自己去组装这玩意,相当于我们在TCP那个中的send,recv之后发出的ok那玩意,区别就是TCP中我们不需要自己去组装这格式
那么HTTP报文中那些东西究竟什么意思呢?这玩意解释起来贼麻烦,都在《Linux高性能服务器编程》中,我将这本书的pdf格式的电子书放在下面的链接中了
链接:https://pan.baidu.com/s/19x4ZB9wCNenq0YU5IBX72w
提取码:1234
下面来编写一个简单的HTTP服务器:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int socket_init();int main()
{int sockfd = socket_init();assert(sockfd != -1);while(1){struct sockaddr_in caddr;int len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*)&caddr,&len);if(c < 0){continue;}char buff[1024] = {0};int n = recv(c,buff,1023,0); //接收浏览器发来的数据if(n == 0) //n == 0 的话 就是客户端关闭了{close(c);continue;}printf("recv = %s \n",buff);send(c,"helo HTTP",9);close(c);}
}int socket_init()
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建套接字 SOCK_DGRAM这个为UDP数据报套接字assert(sockfd != -1);struct sockaddr_in saddr; memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(80); //HTTP默认端口为80号端口saddr.sin_addr.s_addr = inet_addr("192.168.0.115");int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res == -1){return -1;}if(listen(sockfd,5) == -1){return -1;}return sockfd;
}
在上面的第50行代码中的IP绑定中,使用的是192.168.0.115这个真实IP(也可以使用127.0.0.1这个本机IP,查看本机IP(Linux中是ifconfig,Windows中是ipconfig)),要是使用了本机IP的话,只能本机访问,例如在虚拟机中的火狐浏览器访问,而本身的Windows就不能访问这个服务器,使用真实IP的话,Windows和Ubuntu中都可以访问:
当我们一切准备就绪准备运行这个服务器的时候:
发现sockfd = -1 ,查看代码发现使用的端口号是80,端口号5000以内的都是管理员才有权限使用的端口,所以我们切换一下管理员权限:
sudo su
然后就可以让服务器跑起来了,然后我们在Ubuntu和Windows中都对它进行以下访问:
上图我们在服务器中写的hello HTTP 的内容显示到了屏幕上
上图就是在运行服务器之后,被别人访问之后我们后台看到的东西,可以看出来实在Ubuntu加二Windows上面访问的,浏览器分别为chorm浏览器和火狐(Firefox)浏览器,而在下方那个.ico的东西是小图标,而我们为什么没有出现上方图片中的HTTP请求报文和HTTP的应答报文的呢?那玩意那个报文得自己去组装,这里说一下思路,获取我们在访问的时候的文件名字,来判断浏览器想要服务器的什么文件,还有那个应答报文中的content-length这个就是获取报文的大小,会用到lseek这个函数,将大小返回.这样就基本将应答报文组装完成了!