C语言实现url解析小实例

2023-11-08

一、前言

前面一口君写了一篇关于url的文章:
一文带你理解URI 和 URL 有什么区别?

本篇在此基础上,编写一个简单的用于解析url的小例子,

最终目标是解析出URL中所有的数据信息。

二、库函数

用到的几个库函数如下:

1. strncasecmp

头文件

#include<string.h>

函数定义

int strncasecmp(const char *s1,const char *s2,size_t n);

函数说明

用来比较参数s1和s2字符串前n个字符,比较时会自动忽略大小写的差异。

返回值

若参数s1和s2 字符串相同则返回0。
s1 若大于s2则返回大于0的值,
s1若小于s2则返回小于0 的值。

2. strstr

头文件

#include<string.h>

函数定义

char *strstr( const char* str, const char* substr );

函数说明

查找 substr 所指的空终止字节字符串在 str 所指的空终止字节字符串中的首次出现。不比较空终止字符。

若 str 或 substr 不是指向空终止字节字符串的指针,则行为未定义。

参数

str	:指向要检验的空终止字节字符串的指针
substr	:指向要查找的空终止字节字符串的指针

返回值

指向于 str 中找到的子串首字符的指针,或若找不到该子串则为空指针。若 substr 指向空字符串,则返回 str 。

3. strtok

函数定义

 char *strtok(char *str, const char *delim)

功能

分解字符串 str 为一组字符串,delim 为分隔符

参数

str -- 要被分解成一组小字符串的字符串。
delim -- 包含分隔符的 C 字符串。

返回值

该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

4. strncpy

函数说明

char *strncpy(char *dest, const char *src, size_t n)

功能

将src指向的字符串拷贝到dest执行的内存中,最多拷贝n个字符

参数

dest -- 指向用于存储复制内容的目标数组。
src -- 要复制的字符串。
n -- 要从源中复制的字符数。

返回值

该函数返回最终复制的字符串。

5. inet_pton/inet_ntop

头文件

       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <arpa/inet.h>

函数声明

#include <arpe/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);     

功能:

将点分十进制的ip地址转化为用于网络传输的数值格式
对于IPv4地址和IPv6地址都适用

参数

family:协议类型既可以是AF_INET(ipv4)也可以是AF_INET6(ipv6)。如果,以不被支持的地址族作为family参数,这两个函数都返回一个错误,并将errno置为EAFNOSUPPORT.

strptr:指向点分十进制的IP地址字符串,比如"192.168.1.1"

addrptr:转换结果存放在addrptr中,比如"192.168.1.1"转换为:0xC0A80101

addrptr类型为:struct in_addr 
typedef uint32_t in_addr_t;
struct in_addr {
    in_addr_t s_addr;
};

返回值

若成功则为1,若输入不是有效的表达式则为0,
若出错则为-1
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len);     

功能

将数值格式转化为点分十进制的ip地址格式,从数值格式(addrptr)转换到表达式(strptr)

返回值

若成功则为指向结构的指针,若出错则为NULL

6. gethostbyname

函数的定义

#include <netdb.h>
struct hostent * gethostbyname(const char * hostname);   

功能

解析hostname指向的域名,该函数会将该域名封装到DNS协议包中,发送给DNS服务器,DNS服务器会将该域名对应的地址返回,存储在struct hostent中

参数

hostname :存储域名对应的字符串。

返回值

若成功则为非空指针,若出错则为NULL且设置h_errno
返回的指针类型为:
struct hostent{
    char *h_name;  //official name
    char **h_aliases;  //alias list
    int  h_addrtype;  //host address type
    int  h_length;  //address lenght
    char **h_addr_list;  //address list
}
DNS服务器返回的地址就存储在该结构体中

三、自定义结构

结构体用于存放需要解析的协议和端口号

struct pro_port{
	char pro_s[32];
	unsigned short port;
};

目前本例子只解析以下集中协议,读者需要支持其他协议可以按照该格式增加对应信息即可

#define HEAD_FTP_P "ftp://"
#define HEAD_FTPS_P "ftps://"   
#define HEAD_FTPES_P "ftpes://"
#define HEAD_HTTP_P "http://"
#define HEAD_HTTPS_P "https://"


#define PORT_FTP  21
#define PORT_FTPS_I  990    //implicit
#define PORT_FTPS_E  21     //explicit
#define PORT_HTTP 80
#define PORT_HTTPS 443
struct pro_port g_pro_port[]={
	{HEAD_FTP_P,PORT_FTP},
	{HEAD_FTPS_P,PORT_FTPS_I},	
	{HEAD_FTPES_P,PORT_FTPS_E},	
	{HEAD_HTTP_P,PORT_HTTP},	
	{HEAD_HTTPS_P,PORT_HTTPS},
};

四、程序流程图


程序流程相对来说,比较简单,主函数功能说明如下:

1. parse_url()

int parse_url(char *raw_url,URL_RESULT_T *result)

参数:

raw_url:指向一个url字符串,比如:ftp://peng:pass@baidu.com/dir/index.html
result :url解析后的结果存放在该结构体中

结构体类型定义如下:
typedef struct
{
	char user[MAX_USER_LEN];
	char pass[MAX_PASS_LEN];
	char domain[INET_DOMAINSTRLEN];//域名
	char svr_dir[MAX_PATH_FILE_LEN]; //文件路径
	char svr_ip[MAX_IP_STR_LEN];
	int port;
}URL_RESULT_T;

功能:

解析url字符串,并将解析结果存放在result中

返回值;

成功返回 URL_OK
失败返回 URL_ERROR 

2. void remove_quotation_mark()

void remove_quotation_mark(char *input)

参数

input:字符串

功能

去掉字符串中的双引号 \"

返回值

3. parse_domain_dir

int  parse_domain_dir(char *url,URL_RESULT_T *result)

参数

url:执行去掉协议头的url字符串,比如:peng:pass@baidu.com/dir/index.html
result :url解析后的结果存放在该结构体中

功能

解析出url中用户名、密码、域名/ip、文件路径等信息

返回值

成功:URL_OK
失败:URL_ERROR

4. check_is_ipv4()

int check_is_ipv4(char *domain)

参数

domain:指向一个域名或者IP地址点分十进制字符串,最大长度为:MAX_URL_LEN

功能

判断domain中存放的是不是合法的IP地址

返回值

1:是IP地址
-1:不是IP地址

5、dns_resoulve()

int dns_resoulve(char *svr_ip,const char *domain)

参数

svr_ip:存放DNS协议解析过的域名对应的IP地址点分十进制字符串
domain:域名字符串

功能

将domain中的域名,通过DNS协议解析成对应的IP地址

返回值

成功:URL_OK
失败:URL_ERROR

五、运行

测试程序

void main(void)
{
	int ret;
	
	char url_str[256]="ftp://peng:pass@baidu.com/dir/index.html";
	parse_url(url_str,&url_result_t);

	ret = check_is_ipv4(url_result_t.domain);	
	if(ret != 1)
	{	
		//dns
		dns_resoulve(url_result_t.svr_ip,url_result_t.domain);
	}
	printf("\n-------------result---------------\n");

	printf("user:%s\n",url_result_t.user);
	printf("pass:%s\n",url_result_t.pass);
	printf("port:%d\n",url_result_t.port);
	printf("domain:%s\n",url_result_t.domain);
	printf("svr_dir:%s\n",url_result_t.svr_dir);
	printf("svr_ip:%s\n",url_result_t.svr_ip);

	printf("-------------end---------------\n");
}

执行结果

六、代码获取

完整代码可以进入我的仓库获取

https://gitee.com/yikoulinux/url

或者公众号后台回复关键字:url

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言实现url解析小实例 的相关文章

随机推荐

  • 【Vue】同一模板 多个样式 统一实现

    文章目录 一 背景 二 具体代码 一 背景 项目中多个页面的页脚都包含版权信息 并且各自有一个 Copyright vue 的组件 经过对比 template 的内容一模一样 只是样式有些不同 这里准备抽取出来 用一个公共组件 CopyRi
  • 你的电脑上的应用需要使用以下window功能.NET Framework3.5(包括.NET2.0和3.0)

    我自己下载了 net 3 5来安装他也提示这玩意 然后点自动安装后又错误码0x800f081f 奶奶滴 于是去百度 解决流程 1 首先 按Windows R调出 运行 对话框 2 接下来 键入gpedit msc并按Enter 3 该命令将
  • pytorch将Tensor转为list

    import torch value torch Tensor 1 2 3 print list value tolist 得到 list 1 0 2 0 3 0
  • promise与async和await的使用

    基础回顾 阻塞代码实例 首先 我们新建一个 test txt 文件 内容如下 111 然后 我们来编写一个 main js 文件 代码如下 var fs require fs var str fs readFileSync test txt
  • css button自动调整位置_(Vue动效)1.Vue的CSS过渡动效

    关键词
  • JAVA个推----将信息推送至手机端

    个推功能简介 将信息推送至手机端 手机端人员可以看到收到的信息 个推功能需要借助第三方平台的接口 需要申请账号 单独开发很难完成 这里就是用到了第三方接口 完成个推需要完成三步 获取token 调用个推接口需要获取用于验证的token 获取
  • 前端歌谣的刷题之路-第二十二题-基本数据类型检测

    前言 我是歌谣 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷 本题目源自于牛客网 微信公众号前端小歌谣 题目 请补全JavaScript函数 要求以字符串的形式返回参数的类型 注意 只需检测基本数据类型 编辑 核心代码
  • 自动驾驶制图中的深度学习

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 深度学习在整个自动驾驶技术的各个部分中进行了应用 例如在感知 预测和计划中都有应用 同时 深度学习也可以用于制图 这是高级自动驾驶的关键组成部分 拥有准确的地图对于自动驾
  • Siebel学习笔记

    Siebel escript 的学习 1 Siebel的数据类型 Primitive 原始的 Number Integer Hexadecimal 十六进制 Octal 八进制 Floating Point 浮点 Decimal 十进制 S
  • 面试总结(1)---7.28

    Ajax关于readyState 状态值 和status 状态码 的研究 var getXmlHttpRequest function try 主流浏览器提供了XMLHttpRequest对象 return new XMLHttpReque
  • 解决wiringPi库与64位树莓派之间不兼容的问题

    目录 一 问题现象 二 解决方案 网站 可以直接点这下载 一 问题现象 今天在练习wiringPi库的使用时候 在最后编译的时候出现了这个问题 主要问题是这个skipping incompatible skipping incompatib
  • Android上OpenCV物体检测,Opencv图像识别Android实战(识别纸牌4.图像识别素养)

    我认为大多数阅读本文的人都对机器学习有所了解 我认为没有必要在学术上解释这种含义 人类学习的目的不是识别更多的东西 机器学习也是如此 也就是说 让计算机通过学习类比来学习更多的东西 在这里 我们让计算机知道图像 要让计算机知道事情 我们必须
  • 集成学习笔记

    集成学习通过结合规则 使用一系列弱学习器来组成一个强学习器 集成学习通常有两个步骤 ensemble generation 和 ensemble integration 通常在两个步骤之间会有一个 pruning process 剪枝过程
  • LeetCode--初级算法--环形链表

    题目 给定一个链表 判断链表中是否有环 为了表示给定链表中的环 我们使用整数 pos 来表示链表尾连接到链表中的位置 索引从 0 开始 如果 pos 是 1 则在该链表中没有环 示例 1 输入 head 3 2 0 4 pos 1 输出 t
  • Excel条件格式化(conditional formatting)应用

    简介 条件格式化顾名思义就是根据条件对单元格进行格式化 填充 字体等 比如我们有一个学生成绩表 根据需要我们要把成绩按 不及格 lt 60 良好 gt 60且 lt 90 优秀 gt 90 进行颜色标注 第一步 如图 第二步 如图 点击 确
  • OpenMP task 原理与实例

    个人理解 Openmp自从3 0以后全面走向任务驱动 task机制非常重要 可以显式定义任务 而其余parallel代码块中不用task定义的实际上是隐式任务 抽象来说就是有两个池子 线程池与任务池 闲置的线程会在线程池等待任务 显式任务与
  • Servlet登录注册(IDEA)

    user类 提供get set 有参 无参 toString方法 UserDao层 UserDaoImpl层 登录 注册是否重复 真正的注册 UserService层 登录LoginServlet层 注册和注册用户唯一的ZcServlet层
  • html,css,js简单介绍,html常用标签

    目录 简单介绍 HTML常用标签 1 html骨架标签 2 标题标签 3 段落标签 4 换行标签 5 文本格式化标签 6 div标签 span标签和pre标签 7 图像标签 8 超链接标签 9 注释标签 10 表格标签 11 列表标签 12
  • Geometry Shader 概念和实例

    前言 Shader Model 4给我们带来了Geometry Shader这个玩意儿 其实这个东西早就在一些3D动画制作软件中存在了 比如Maya 8 我参考了以前DX10的哪一篇Preview与Csustan edu的一篇比较详尽的教材
  • C语言实现url解析小实例

    一 前言 前面一口君写了一篇关于url的文章 一文带你理解URI 和 URL 有什么区别 本篇在此基础上 编写一个简单的用于解析url的小例子 最终目标是解析出URL中所有的数据信息 二 库函数 用到的几个库函数如下 1 strncasec