C/C++实现HTTP协议解析的示例代码

超文本传输协议 (HTTP) 是分布式、协作、超媒体信息系统的应用层协议。 这是自 1990 年以来万维网数据通信的基础。HTTP 是一种通用且无状态的协议,它可以用于其他目的,也可以使用其请求方法、错误代码和标头的扩展。

基本上,HTTP 是一种基于 TCP/IP 的通信协议,用于通过 Web 传递 HTML 文件、图像文件、查询结果等数据。 它为计算机之间的通信提供了一种标准化的方式。 HTTP 规范指定了客户端请求的数据如何发送到服务器,以及服务器如何响应这些请求。

HTTP客户端和服务器通信

客户端和服务器通过交换单独的消息(而不是数据流)进行通信。 客户端(通常是 Web 浏览器)发送的消息称为请求,服务器发送的作为应答的消息称为响应。

HTTP通过 TCP 或 TLS 加密的 TCP 连接发送的应用层协议,尽管理论上可以使用任何可靠的传输协议。 由于其可扩展性,它不仅用于获取超文本文档,还用于获取图像和视频或将内容发布到服务器,例如 HTML 表单结果。 HTTP 还可用于获取部分文档以按需更新网页。

HTTP和连接

连接是在传输层控制的,因此基本上超出了 HTTP 的范围。 HTTP 不要求底层传输协议是基于连接的;

它只要求它是可靠的,或者不丢失消息。在 Internet 上最常见的两种传输协议中,TCP 是可靠的,而 UDP 则不是。因此,HTTP 依赖于基于连接的 TCP 标准。

在客户端和服务器可以交换 HTTP 请求/响应对之前,它们必须建立 TCP 连接,这个过程需要多次往返。

HTTP/1.0 的默认行为是为每个 HTTP 请求/响应对打开一个单独的 TCP 连接。当多个请求连续发送时,这比共享单个 TCP 连接效率低。

HTTP 消息

HTTP/1.1 及更早版本中定义的 HTTP 消息是人类可读的。 在 HTTP/2 中,这些消息被嵌入到二进制结构中,即一个帧,允许像压缩头和多路复用这样的优化。 即使在这个版本的 HTTP 中只发送原始 HTTP 消息的一部分,每个消息的语义都不会改变,客户端会(实际上)重构原始 HTTP/1.1 请求。 因此,理解 HTTP/1.1 格式的对 HTTP/2 消息很有用。

HTTP 消息有两种类型,请求和响应,每种都有自己的格式。

HTTP请求消息

请求由以下元素组成:

HTTP 方法,通常是 GET、POST 之类的动词或 OPTIONS 或 HEAD 之类的名词,用于定义客户端想要执行的操作。 通常,客户端想要获取资源(使用 GET)或发布 HTML 表单的值(使用 POST),但在其他情况下可能需要更多操作。

要获取的资源的路径; 从上下文中明显的元素中剥离的资源的 URL。

HTTP响应消息

响应由以下元素组成:

他们遵循的 HTTP 协议的版本。

状态码,指示请求是否成功以及原因。

状态消息,状态代码的非权威简短描述。

HTTP 标头,例如用于请求的标头。

可选地,包含获取的资源的主体。

HTTP 状态

一些常见的 HTTP 状态代码包括:

200 - 请求成功(网页存在)
 301 - 永久移动(通常转发到新 URL)
 401 - 未经授权的请求(需要授权)
 403 - 禁止(不允许访问页面或目录)
 500 - 内部服务器错误(通常由不正确的服务器配置引起)

HTTP协议解析及C/C++代码实现

...
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{

    ...

	/* print source and destination IP addresses */
	printf("       From: %s\n", inet_ntoa(ip->ip_src));
	printf("         To: %s\n", inet_ntoa(ip->ip_dst));

	/* determine protocol */
	switch(ip->ip_p)
	{
		case IPPROTO_TCP:
			printf("   Protocol: TCP\n");
			break;
		case IPPROTO_UDP:
			printf("   Protocol: UDP\n");
			break;
		case IPPROTO_ICMP:
			printf("   Protocol: ICMP\n");
			return;
		case IPPROTO_IP:
			printf("   Protocol: IP\n");
			return;
		default:
			printf("   Protocol: unknown\n");
			return;
	}

	/*
	 *  OK, this packet is TCP.
	 */

	/* define/compute tcp header offset */
	if(ip->ip_p == IPPROTO_TCP)
	{
        ...

		printf("   Src port: %d\n", ntohs(tcp->th_sport));
		printf("   Dst port: %d\n", ntohs(tcp->th_dport));
		int sport = ntohs(tcp->th_sport);
		int dport = ntohs(tcp->th_dport);

        ...
		if (size_payload > 0)
		{
			printf("   Payload (%d bytes):\n", size_payload);
			//print_payload(payload, size_payload);

            if ((sport == 80) || (dport == 80))
			{
				printf("   HTTP prase:\n");
				prase_http(payload, size_payload);
			}
			else if(sport == 443 || dport == 443)
			{
				printf("   SSL/TLS prase:\n");
				prase_ssl_tls(payload, size_payload);
			}
		}
	}
	...

}

int main(int argc, char *argv[])
{

	char errbuf[100];
	pcap_t *desc = 0;
    char *filename = argv[1];
    if (argc != 2)
    {
        printf("usage: ./dissect_http [pcap file]\n");
        return -1;
    }

    printf("ProcessFile: process file: %s\n", filename);
    if ((desc = pcap_open_offline(filename, errbuf)) == NULL)
    {
        printf("pcap_open_offline: %s error!\n", filename);
        return -1;
    }   	

    pcap_loop(desc, -1, got_packet, NULL);

    pcap_close(desc);
    return 0;
}

运行结果:

总结

HTTP 是一种易于使用的可扩展协议。 客户端-服务器结构与添加标头的能力相结合,允许 HTTP 与 Web 的扩展功能一起发展。

尽管 HTTP/2 通过在帧中嵌入 HTTP 消息来提高性能增加了一些复杂性,但消息的基本结构自 HTTP/1.0 以来一直保持不变。 会话流保持简单,允许使用简单的 HTTP 消息监视器对其进行调查和调试。

以“http://”开头的 URL 通过标准超文本传输​​协议访问,默认使用端口 80。以“https://”开头的 URL 通过安全的 HTTPS 连接访问,通常使用端口 443。

以上就是C/C++代码实现HTTP协议解析的示例代码的详细内容,更多关于C++解析HTTP协议的资料请关注我们其它相关文章!

(0)

相关推荐

  • c语言实现http下载器的方法

    一.介绍 最近做ota升级需要用到http下载,所以写了一下http下载器 实现流程 1.解析url网址的域名和文件名 2.获取ip地址 3.构建http请求头发送到服务器 4.解析回复 5.下载文件 环境ubuntu linux c语言 开源链接 main.c #include <stdio.h> #include "http_download.h" int main(int argc, char const *argv[]) { if (argc == 1) { pri

  • C/C++ 实现简易HTTP服务器的示例

    #include <stdio.h> #include <stdlib.h> #include <process.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define BUF_SIZE 2048 #define BUF_SMALL 100 void Send_404(SOCKET sock) { char Protocol[] = "HTTP/1.

  • c语言http请求解析表单内容

    cgi.h 复制代码 代码如下: #ifndef CGI_H#define CGI_H #include <stdio.h>#include <string.h>#include <stdlib.h> typedef struct Node{ char *name; char *value; struct Node *next;}Node; typedef struct Index{ Node *head; char *buffer;}Index; Index *get

  • C++发送HTTP请求的实现代码

    复制代码 代码如下: #include <stdio.h>#include <windows.h>#include <wininet.h> #define MAXSIZE 1024#pragma comment(lib, "Wininet.lib") void urlopen(_TCHAR*); int _tmain(int argc, _TCHAR* argv[]){    urlopen(_T("http://coderzh.cnblo

  • 10行C++代码实现高性能HTTP服务

    前言 是不是觉得C++写个服务太累,但又沉迷于C++的真香性能而无法自拔?作为一个老牌C++程序员(可以看我 github 上十几年前的C++项目:https://github.com/kevwan ),这几天听一个好友跟我聊起他写的C++框架,说极简代码即可完成各种C++服务的开发,不禁让我心生好奇!于是我去研究了一下,发现确实有点意思! 实战(干货) 话不多说,我们来一起看看,10行C++代码怎么实现一个高性能的Http服务,轻松QPS几十万.Linus说:talk is cheap,sho

  • c++实现发送http请求通过get方式获取网页源代码

    复制代码 代码如下: #include <stdio.h>#include <windows.h>#include <wininet.h>#define MAXSIZE 1024#pragma comment(lib, "Wininet.lib") void urlopen(_TCHAR*); int _tmain(int argc, _TCHAR* argv[]){    urlopen(_T("http://www.jb51.net&q

  • C++ 实现高性能HTTP客户端

    目录 一.什么是Http Client 二.请求的过程 1. 创建Http任务 2. 填写header并发出 3. 处理返回结果 三.高性能的基本保证 1. 异步调度模式 2. 连接复用 3. 解锁其他功能 一.什么是Http Client Http协议,是全互联网共同的语言,而Http Client,可以说是我们需要从互联网世界获取数据的最基本方法,它本质上是一个URL到一个网页的转换过程.而有了基本的Http客户端功能,再搭配上我们想要的规则和策略,上至内容检索下至数据分析都可以实现了. 继

  • C/C++实现HTTP协议解析的示例代码

    超文本传输协议 (HTTP) 是分布式.协作.超媒体信息系统的应用层协议. 这是自 1990 年以来万维网数据通信的基础.HTTP 是一种通用且无状态的协议,它可以用于其他目的,也可以使用其请求方法.错误代码和标头的扩展. 基本上,HTTP 是一种基于 TCP/IP 的通信协议,用于通过 Web 传递 HTML 文件.图像文件.查询结果等数据. 它为计算机之间的通信提供了一种标准化的方式. HTTP 规范指定了客户端请求的数据如何发送到服务器,以及服务器如何响应这些请求. HTTP客户端和服务器

  • 使用Apache commons-cli包进行命令行参数解析的示例代码

    Apache的commons-cli包是专门用于解析命令行参数格式的包. 依赖: <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.3.1</version> </dependency> 使用此包需要: 1.先定义有哪些参数需要解析.哪些参数有额外的选项.每个参数的描述等等,对应

  • web项目开发中2个Token原因解析及示例代码

    目录 问题: 项目中2个Token, 一个时效2个小时(简称:短Token), 另一个时效14天(简称:长Token), 为什么要用2个Token? 解答: 1.基于安全性, 防止Token泄露的考虑, 服务器资源中所有的请求都只能使用短Token, 并且短Token只有2小时时效; 这个方法依然无法完全解决防止Token泄露的问题, 只是在一定程度上提高防止Token泄露的安全性; 长Token的作用只有一个, 就是短Token时效了的时候, 用长Token去请求获取新的短Token, 只有这

  • 在java中使用dom4j解析xml(示例代码)

    虽然Java中已经有了Dom和Sax这两种标准解析方式 但其操作起来并不轻松,对于我这么一个初学者来说,其中部分代码是活生生的恶心 为此,伟大的第三方开发组开发出了Jdom和Dom4j等工具 鉴于目前的趋势,我们这里来讲讲Dom4j的基本用法,不涉及递归等复杂操作 Dom4j的用法很多,官网上的示例有那么点儿晦涩,这里就不写了 首先我们需要出创建一个xml文档,然后才能对其解析 xml文档: 复制代码 代码如下: <?xml version="1.0" encoding=&quo

  • Python实现XML文件解析的示例代码

    1. XML简介 XML(eXtensible Markup Language)指可扩展标记语言,被设计用来传输和存储数据,已经日趋成为当前许多新生技术的核心,在不同的领域都有着不同的应用.它是web发展到一定阶段的必然产物,既具有SGML的核心特征,又有着HTML的简单特性,还具有明确和结构良好等许多新的特性. test.XML文件 <?xml version="1.0" encoding="utf-8"?> <catalog> <m

  • JAVA Vector源码解析和示例代码

    第1部分 Vector介绍Vector 是矢量队列,它是JDK1.0版本添加的类.继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口.Vector 继承了AbstractList,实现了List:所以,它是一个队列,支持相关的添加.删除.修改.遍历等功能.Vector 实现了RandmoAccess接口,即提供了随机访问功能.RandmoAccess是java中用来被List实现,为List提供快速访问功能的.在Vector中,我们即可以通过

  • 使用jquery解析XML示例代码

    xml文件结构:books.xml <?xml version="1.0" encoding="UTF-8"?> <root> <book id="1"> <name>深入浅出extjs</name> <author>张三</author> <price>88</price> </book> <book id="

  • C#网络请求与JSON解析的示例代码

    最新学校的海康摄像头集控平台(网页端)不能在win10里登录,我寻思着拿海康的c# demo直接改. 首先得解决权限问题,每个教师任教不同年级,只能看到自己所在年级的设备,涉及到登录,在此记录一下C#中网络请求和数据处理的一些内容.大致流程为: 客户端发起登录请求: 服务端验证账号密码 返回json字符串,包含用户信息.平台配置等信息 客户端解析并初始化 一.发起GET请求 private string HttpGet(string api) { string serviceAddress =

  • C# 使用Tcp/Udp协议的示例代码

    所使用的:多线程 委托 Socket 键值队 个人跟着视频做的一个小练习,有兴趣的可以去看一下对于初学者来讲是比较有帮助的 连接:https://www.bilibili.com/video/BV1bZ4y1W74q?p=3&t=358 废话不多说上代码  综合视频中的理解 有什么不对的地方希望大神指点一下 public partial class Form1 : Form { public Form1() { InitializeComponent(); myAddOnlieDelegate

  • 使用JSP实现简单的用户登录注册页面示例代码解析

    实验要求: 将实验2中的系统用户登录和注册页面改为JSP页面,并部署自己的Web应用于Tomcat服务器中 具体要求: 完成登录JSP页面设计和注册页面设计 在登录页面表单中使用request对象获取用户信息,建立新的JSP页面完成登录验证(用户名和密码自己指定即可). 验证结果显示(如登录成功/用户名密码错误,可以使用JavaScript,也可以使用新的JSP页面). 在注册页面表单中使用request对象获取用户注册信息(注册项目由自己指定),在新的JSP页面显示用户注册信息,并提示注册成功

随机推荐