C/C++ Linux网络编程10 - http协议

上篇文章:C/C++ Linux网络编程9 -服务器的独立运行-CSDN博客

代码仓库:橘子真甜 (yzc-YZC) - Gitee.com

目录

[一. 服务器设计流程](#一. 服务器设计流程)

[二. http协议](#二. http协议)

[2.1 URL网址](#2.1 URL网址)

[2.2 http请求Request](#2.2 http请求Request)

[2.3 http响应Response](#2.3 http响应Response)

[2.4 细节补充](#2.4 细节补充)

[三. 代码验证](#三. 代码验证)

[3.1 发送简单HTTP响应](#3.1 发送简单HTTP响应)

[四. GET/POST方法获取数据](#四. GET/POST方法获取数据)


一. 服务器设计流程

我们知道,OSI七层网络模型为:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。**而我们网络编程一般是从传输层开始的。**具体过程如下:

服务器:socket,bind,listen,accept,recv,协议解析与数据处理,send, close。

客户端:socket,connect(系统自行bind),send,recv接收响应,close。

这些接口在网络模型哪些层工作呢?

传输层:负责两个节点之间的数据传输,如有需要,可以保证可靠性。包含接口是 socke,read,write,recv,send。bind,listen,connect,accept。

会话层:负责两个节点之间建立和断开连接:连接,会话等管理

表示层:负责设计数据和网络数据之间的转换:序列化,反序列化,加密解密等。

应用层:负责特定的应用层协议:协议解析,http/https,ssh等具体协议

二. http协议

http是超文本传输协议,服务器提供客户端可以访问资源的路径,其他用户通过url网址和http协议获取/访问/我们开放的资源,也能提交/更新/删除资源和数据。

2.1 URL网址

使用 ip+端口确实能够访问我们的服务器,但是不太容易记忆。为了方便用户和客户端解析。客户端通过URL网址来访问服务器资源。

https:协议名称

bolg.csdn.net:域名,通过DNS解析为ip地址

yzcllzx?type=blog:表示我们访问的资源,即服务器的某一个文件路径。

为何不需要端口呢?因为http和https已经固定好端口了(http:80 https:443)

2.2 http请求Request

http响应是浏览器/客户端向服务器发起的。格式如下:

bash 复制代码
//第一部分是请求行,包含多种请求方法
请求方法(GET/POST) url http版本(1.0 1.1 2.0 3.0)\r\n

//第二部分是请求报头,包含多行kv字段,由:分割。末尾以\r\n结尾
name1: value1\r\n
name2: value2\r\n
name3: value3\r\n
name4: value4\r\n

//第三部分是一个空行,表示请求头部结束
\r\n

//第四部分是请求的正文,可以没有正文,也可以是由客户端发送的请求数据,有正文,第二部分就有正文长度
username="yzc"&password="123456"

2.3 http响应Response

http响应是由服务器返回给客户端的,最终在浏览器显示的资源

bash 复制代码
//响应的第一部分是一个状态行
http版本 状态码 状态码描述\r\n

//第二部分是响应头部,和请求一样由多个kv表示
name1: value1\r\n
name2: value2\r\n
name3: value3\r\n
name4: value4\r\n

//第三部分是空行,表示头部结束
\r\n

//第四部分是响应的正文部分,包含服务器返回的资源
html/css/js/视频/音频/文本/数据/图片...

2.4 细节补充

http状态码:

|-----|----------|-------------|
| | 类别 | 说明 |
| 1xx | 信息性状状态码 | 表示服务器正在处理请求 |
| 2xx | 成功状态码 | 表示服务器正常处理完毕 |
| 3xx | 重定向状态码 | 需要附加操作完成请求 |
| 4xx | 客户端错误状态码 | 服务器无法处理请求 |
| 5xx | 服务端错误状态码 | 服务器处理请求出错 |

http常见头部

|----------------|----------------------|
| Content-Type | 数据的类型 |
| Content-Length | 数据的长度 |
| Host | 告知客户端访问资源的端口 |
| User-Agent | 客户端声明自己的软件/操作系统等信息 |
| referer | 这个页面是从哪一个页面跳转过来 |
| location | 与状态码3xx联合使用,表示跳转的为位置 |
| Cookie | 用于客户端存储少量信息,可以实现会话 |

http常见方法

主要方法如下表

|--------|--------|
| GET | 用于获取资源 |
| POST | 传输实体主体 |
| PUT | 传输文件 |
| DELETE | 删除文件 |

还有其他方法比如:HEAD,OPTIONS,TRACE,CONNECT,LINK,UNLINK

1 HTTP请求/响应是如何做到序列化和反序列化的?

可以直接使用库处理,或者使用第三方库

2 如何保证读取一个完整的请求。响应?

while循环读取一行数据(\r\n结尾),如果读到空行表示请求。响应头部读取完毕了。然后根据头部的一个字段Content-Length来读取正文。这样就能实现读取一个完整的响应,请求

三. 代码验证

首先拿到我们之前的reactorTCP服务器代码:ReactorTCP服务器代码

这里我们直接将客户端的信息进行打印返回

收到的HTTP请求如下:

cpp 复制代码
GET / HTTP/1.1
Host: 47.105.37.157:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

3.1 发送简单HTTP响应

cpp 复制代码
void serviceHTTP(connItem *conn)
{
    printf("client --> server:\n%s", conn->_inbuffer.c_str());
    conn->_inbuffer.clear();
    // 这里仅做简单的数据收发
    std::string body = "<h1>Hello World!</h1>";

    // 响应行
    conn->_outbuffer = "HTTP/1.1 200 OK\r\n";

    // 响应头
    conn->_outbuffer += "Content-Type: text/html; charset=utf-8\r\n";
    conn->_outbuffer += ("Content-Length: " + std::to_string(body.size()) + "\r\n");

    // 响应空行
    conn->_outbuffer += "\r\n";

    // 响应主体
    conn->_outbuffer += body;

    // 无脑向客户端发送一个简单http响应
    conn->_sender(conn);
}

四. GET/POST方法获取数据

GET是用于获取服务器指定路径资源的方法。如果需要提交数据,GET是通过拼接的方式将参数添加到指定目录的末尾。服务端通过解析获取客户端提交的数据。GET方法提交参数不能过长,并且隐私性并不是很好

如果使用POST方法,则是将参数提交到请求的正文中。服务端解析正文获取数据。这种方式能够提交更大的数据 甚至可以是其他的内容(比如图片,视频,大型文档)并且隐私性更好

但是这两种方式传输数据都是不安全的 。想要安全必须使用HTTPS

相关推荐
dishugj4 小时前
【linux】Redhat 6.3系统安装zabbix-agent软件包,无法使用YUM源问题
linux·运维·zabbix
sweet丶5 小时前
DNS域名解析:从入门到优化必备基础
网络协议
无奈笑天下5 小时前
【麒麟镜像vmtools异常排查指导书】
linux·运维·经验分享·云计算·kylin
Xの哲學5 小时前
Linux多级时间轮:高精度定时器的艺术与科学
linux·服务器·网络·算法·边缘计算
FlourishingMind5 小时前
蓝牙授时CTS (Current Time Service)、PTP、NTP
运维·服务器·网络
阿闽ooo5 小时前
外观模式:从家庭电源控制看“简化接口“的设计智慧
c++·设计模式·外观模式
QT 小鲜肉6 小时前
【Linux命令大全】001.文件管理之mmove命令(实操篇)
linux·服务器·前端·chrome·笔记
Winner13006 小时前
查看rk3566摄像头设备、能力、支持格式
linux·网络·人工智能
MaximusCoder6 小时前
Linux信息收集Command
运维·服务器·经验分享
QT 小鲜肉6 小时前
【Linux命令大全】001.文件管理之mdel命令(实操篇)
linux·运维·服务器·chrome·笔记