HTTP(超文本传输协议)工作在应用层,是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
认识URL
http://URL/路径
-
http:// —>协议名
-
URL—>服务器ip地址+
:
+端口号;标志着我们服务器进程的位置(可和相关域名绑定让用户更容易记忆) -
/路径—>网页根目录(一般设置为wwwroot)下的文件,默认为index.html
HTTP协议格式
HTTP请求格式
首行: [请求方式] + [url] + [协议版本]
Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
Body: 空行分隔符后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个
Content-Length属性来标识Body的长度;
HTTP响应格式
首行: [协议版本] + [状态码] + [状态码描述]
Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
Body: 空行分隔符后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个
Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在
body中.
实现一个简单的HTTP服务器
这里不用实现客户端了,我们可以用手机/电脑/平板的浏览器直接通过http协议访问我们的server;
http_server.hpp
#pragma once
#include <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/wait.h>
#include <cstdio>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <pthread.h>
#include <string>
using namespace std;
//方便制订响应报文使用
#define HTTP_VERSION "HTTP/1.0"
#define HOME_PAGE "wwwroot/index.html"
#define PAGE_ERROR "wwwroot/404.html"
class HttpServer
{
int listen_sock;
int _port;
public:
TcpServer(int port) : _port(port)
{
}
void Init()
{
listen_sock = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(_port);
server.sin_addr.s_addr = INADDR_ANY;
if (bind(listen_sock, (sockaddr *)&server, sizeof(server)))
{
cerr << "bind error" << endl;
exit(1);
}
//服务器初始化完成,进入监听状态;
listen(listen_sock, 5);
}
static void *fun(void *p) //类里搞多线程的执行函数毕需static,不然会多一个参数导致匹配不上;
{
int sock = *(int *)p;
delete (int *)p;
//接收请求部分
char buff1[4096];
buff1[0] = 0;//清空;
cout << "###################################" << endl;
int c = recv(sock, buff1, sizeof(buff1)