一、前言
前面一口君写了一篇关于url的文章:《一文带你理解URI 和 URL 有什么区别?》
本篇在此基础上,编写一个简单的用于解析url的小例子,
最终目标是解析出URL中所有的数据信息。
二、库函数
用到的几个库函数如下:
1. strncasecmp
头文件
#include
函数定义
intstrncasecmp(constchar*s1,constchar*s2,size_tn);
函数说明
用来比较参数s1和s2字符串前n个字符,比较时会自动忽略大小写的差异。
返回值
若参数s1和s2字符串相同则返回0。
s1若大于s2则返回大于0的值,
s1若小于s2则返回小于0的值。
2. strstr
头文件
#include
函数定义
char*strstr(constchar*str,constchar*substr);
函数说明
查找 substr 所指的空终止字节字符串在 str 所指的空终止字节字符串中的首次出现。不比较空终止字符。
若 str 或 substr 不是指向空终止字节字符串的指针,则行为未定义。
参数
str:指向要检验的空终止字节字符串的指针
substr:指向要查找的空终止字节字符串的指针
返回值
指向于 str 中找到的子串首字符的指针,或若找不到该子串则为空指针。若 substr 指向空字符串,则返回 str 。
3. strtok
函数定义
char*strtok(char*str,constchar*delim)
功能
分解字符串str为一组字符串,delim为分隔符
参数
str --要被分解成一组小字符串的字符串。
delim --包含分隔符的 C 字符串。
返回值
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
4. strncpy
函数说明
char*strncpy(char*dest,constchar*src,size_tn)
功能
将src指向的字符串拷贝到dest执行的内存中,最多拷贝n个字符
参数
dest --指向用于存储复制内容的目标数组。
src --要复制的字符串。
n --要从源中复制的字符数。
返回值
该函数返回最终复制的字符串。
5. inet_pton/inet_ntop
头文件
#include
#include
#include
函数声明
#include
intinet_pton(intfamily,constchar*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类型为:structin_addr
typedefuint32_tin_addr_t;
structin_addr{
in_addr_ts_addr;
};
返回值
若成功则为1,若输入不是有效的表达式则为0,
若出错则为-1
constchar*inet_ntop(intfamily,constvoid*addrptr,char*strptr,size_tlen);
功能
将数值格式转化为点分十进制的ip地址格式,从数值格式(addrptr)转换到表达式(strptr),
返回值
若成功则为指向结构的指针,若出错则为NULL
6. gethostbyname
函数的定义
#include
structhostent*gethostbyname(constchar*hostname);
功能
解析hostname指向的域名,该函数会将该域名封装到DNS协议包中,发送给DNS服务器,DNS服务器会将该域名对应的地址返回,存储在structhostent中
参数
hostname :存储域名对应的字符串。
返回值
若成功则为非空指针,若出错则为NULL且设置h_errno
返回的指针类型为:
structhostent{
char*h_name;//officialname
char**h_aliases;//aliaslist
inth_addrtype;//hostaddresstype
inth_length;//addresslenght
char**h_addr_list;//addresslist
}
DNS服务器返回的地址就存储在该结构体中
三、自定义结构
结构体用于存放需要解析的协议和端口号
structpro_port{
charpro_s[32];
unsignedshortport;
};
目前本例子只解析以下集中协议,读者需要支持其他协议可以按照该格式增加对应信息即可
#defineHEAD_FTP_P"ftp://"
#defineHEAD_FTPS_P"ftps://"
#defineHEAD_FTPES_P"ftpes://"
#defineHEAD_HTTP_P"http://"
#defineHEAD_HTTPS_P"https://"
#definePORT_FTP21
#definePORT_FTPS_I990//implicit
#definePORT_FTPS_E21//explicit
#definePORT_HTTP80
#definePORT_HTTPS443
structpro_portg_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()
intparse_url(char*raw_url,URL_RESULT_T*result)
参数:
raw_url:指向一个url字符串,比如:ftp://peng:pass@baidu.com/dir/index.html
result :url解析后的结果存放在该结构体中
结构体类型定义如下:
typedefstruct
{
charuser[MAX_USER_LEN];
charpass[MAX_PASS_LEN];
chardomain[INET_DOMAINSTRLEN];//域名
charsvr_dir[MAX_PATH_FILE_LEN];//文件路径
charsvr_ip[MAX_IP_STR_LEN];
intport;
}URL_RESULT_T;
功能:
解析url字符串,并将解析结果存放在result中
返回值;
成功返回URL_OK
失败返回URL_ERROR
2. void remove_quotation_mark()
voidremove_quotation_mark(char*input)
参数
input:字符串
功能
去掉字符串中的双引号"
返回值
无
3. parse_domain_dir
intparse_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()
intcheck_is_ipv4(char*domain)
参数
domain:指向一个域名或者IP地址点分十进制字符串,最大长度为:MAX_URL_LEN
功能
判断domain中存放的是不是合法的IP地址
返回值
1:是IP地址
-1:不是IP地址
5、dns_resoulve()
intdns_resoulve(char*svr_ip,constchar*domain)
参数
svr_ip:存放DNS协议解析过的域名对应的IP地址点分十进制字符串
domain:域名字符串
功能
将domain中的域名,通过DNS协议解析成对应的IP地址
返回值
成功:URL_OK
失败:URL_ERROR
五、运行
测试程序
voidmain(void)
{
intret;
charurl_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("
-------------result---------------
");
printf("user:%s
",url_result_t.user);
printf("pass:%s
",url_result_t.pass);
printf("port:%d
",url_result_t.port);
printf("domain:%s
",url_result_t.domain);
printf("svr_dir:%s
",url_result_t.svr_dir);
printf("svr_ip:%s
",url_result_t.svr_ip);
printf("-------------end---------------
");
}
执行结果
六、代码获取
完整代码可以进入仓库获取:
https://gitee.com/yikoulinux/url
原文标题:C语言实现url解析小实例
文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。
审核编辑:汤梓红
-
URL
+关注
关注
0文章
139浏览量
15326 -
编写
+关注
关注
0文章
29浏览量
8441 -
库函数
+关注
关注
0文章
177浏览量
33969
原文标题:C语言实现url解析小实例
文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论