一、前言
前面一口君寫了一篇關於url的文章:《
一文帶你理解URI 和 URL 有什麼區別?
》
本篇在此基礎上,編寫一個簡單的用於解析url的小例子,
最終目標是解析出URL中所有的資料資訊。
二、庫函式
用到的幾個庫函式如下:
1。 strncasecmp
標頭檔案
#include
函式定義
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
函式定義
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 字串。
返回值
該函式返回被分解的第一個子字串,如果沒有可檢索的字串,則返回一個空指標。
嵌入式物聯網開發需要學的東西比較多,就業崗位也是各種各樣。很多人不知道該怎麼學、學什麼?也不知道嵌入式開發做什麼工作比較好。如果你也遇到類似問題,可以點下面連結加我V鑫(備註頭條)。送你一套最新的學習路線圖+100G學習資料+拉你進交流群。
嵌入式物聯網微控制器學習交流
4。 strncpy
函式說明
char *strncpy(char *dest, const char *src, size_t n)
功能
將src指向的字串複製到dest執行的記憶體中,最多複製n個字元
引數
dest —— 指向用於儲存複製內容的目標陣列。src —— 要複製的字串。n —— 要從源中複製的字元數。
返回值
該函式返回最終複製的字串。
5。 inet_pton/inet_ntop
標頭檔案
#include
函式宣告
#include
功能:
將點分十進位制的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”轉換為:0xC0A80101addrptr型別為: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
功能
解析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 443struct 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。htmlresult :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。htmlresult :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://mp。weixin。qq。com/s/vOnOnP581pArydNd6oaB0A
文章轉載自:嵌入式ARM
文章來源於:C語言實現url解析小例項
原文連結:C語言實現url解析小例項