域名解析及HTTP

简介: 域名解析及HTTP

文章目录

域名解析

代码示例

超文本传输协议(HTTP)

代码示例

正则表达式

代码示例


域名解析

URL:统一资源定位符

http://www.sina.com.cn/web/index.html


  • http:// - 协议
  • www.sina.com.cn - 域名
  • /web/index.html - 路径

DNS - 域名解析服务

www.sina.com.cn -> 202.60.121.55, ...
...
#include <netdb.h>
struct hostent* gethostbyname (char const* name);
返回主机条目信息结构指针,失败返回NULL。
hostent
     h_name - 字符指针,指向主机官方名字符串
     h_aliases - 指向字符指针数组的指针,该数组中的每个元素都是字符指针,指向一个别名字符串,最后一个元素是一个NULL指针
     h_addrtype - 地址类型,AF_INET(IPv4)
     h_length - 地址字节数, 4字节(IPv4)
     h_addr_list - 指向结构体指针数组的指针,该数组中的每个元素都指向一个struct in_addr类型的结构体,其中存放着主机一个IP地址,最后一个元素是一个空指针
#include <arpa/inet.h>
char* inet_ntoa (struct in_addr addr);


代码示例

  • dns.c
#include <netdb.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[]) {
  if (argc < 2) {
  printf ("用法:%s <主机域名>\n",
    argv[0]);
  return EXIT_FAILURE;
  }
  struct hostent* host =
  gethostbyname (argv[1]);
  if (! host) {
  perror ("gethostbyname");
  return EXIT_FAILURE;
  }
  if (host->h_addrtype == AF_INET) {
  printf ("主机官方名:\n");
  printf ("\t%s\n", host->h_name);
  printf ("主机别名表:\n");
  char** pp = host->h_aliases;
  while (*pp)
    printf ("\t%s\n", *pp++);
  printf ("主机地址表:\n");
  struct in_addr** pa =
    (struct in_addr**)
    host->h_addr_list;
  while (*pa)
    printf ("\t%s\n",
    inet_ntoa (**pa++));
  }
  return EXIT_SUCCESS;
}


  • 执行结果

2020020817370426.png

超文本传输协议(HTTP)

  1. 请求
GET /web/index.html HTTP/1.0<CR><NL>
Host: www.sina.com.cn
Accept: */*
Connection: Close/Keep-Alive
User-Agent: Mozilla/5.0
Referer: www.sina.com.cn<CR><NL><CR><NL>

  1. 响应
HTTP/1.0 200 OK
Server: nginx
Date: Wed, 26 Oct 2016 10:52:04 GMT
Content-Type: text/html;charset=UTF-8
Content-length: 1234
Connection: Close/Keep-Alive<CR><NL><CR><NL>
<html>
<head> ... </head>
<body> ... </body>
</html>


代码示例

  • http.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
  if (argc < 3) {
  printf ("用法:%s <主机地址> "
    "<主机域名> [<资源路径>]\n",
    argv[0]);
  return EXIT_FAILURE;
  }
  char const* ip = argv[1];
  char const* domain = argv[2];
  char const* path = argc < 4 ?
  "" : argv[3];
  int sockfd = socket (PF_INET,
  SOCK_STREAM, 0);
  if (sockfd == -1) {
  perror ("socket");
  return EXIT_FAILURE;
  }
  struct sockaddr_in addr;
  bzero (&addr, sizeof (addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons (80);
  if (! inet_aton (ip,
  &addr.sin_addr)) {
  perror ("inet_aton");
  return EXIT_FAILURE;
  }
  if (connect (sockfd,
  (struct sockaddr*)&addr,
  sizeof (addr)) == -1) {
  perror ("connect");
  return EXIT_FAILURE;
  }
  char request[1024];
  sprintf (request,
  "GET /%s HTTP/1.0\r\n"
  "Host: %s\r\n"
  "Accept: */*\r\n"
  "Connection: Close\r\n"
  "User-Agent: Mozilla/5.0\r\n"
  "Referer: %s\r\n\r\n",
  path, domain, domain);
  if (send (sockfd, request,
  strlen (request), 0) == -1) {
  perror ("send");
  return EXIT_FAILURE;
  }
  for (;;) {
  char respond[1024] = {};
  ssize_t rlen = recv (sockfd,
    respond,
    sizeof (respond) - 1, 0);
  if (rlen == -1) {
    perror ("recv");
    return EXIT_FAILURE;
  }
  if (! rlen)
    break;
  printf ("%s", respond);
  }
  printf ("\n");
  close (sockfd);
  return EXIT_SUCCESS;
}


  • 执行结果

2020020817535817.png

正则表达式

包含头文件


#include <regex.h>


  • regcomp - 编译正则表达式
  • regexec - 执行正则匹配
  • regfree - 释放正则表达式内存
... href=" http://www.sina.com.cn/web/index.html " ...
href="\s*\([^ >"]*\)\s*"
\s - 匹配任意空白字符(空格、制表、回车、换行)
* - 重复前一个匹配项任意次
[^ >"] - 匹配任意除空格大于号双引号以外的字符
\(和\) - 定义子表达式


代码示例

  • regex.c
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
  if (argc < 2) {
  printf ("用法:%s <HTML文件>\n",
    argv[0]);
  return EXIT_FAILURE;
  }
  FILE* fp = fopen (argv[1], "r");
  if (! fp) {
  perror ("fopen");
  return EXIT_FAILURE;
  }
  if (fseek (fp, 0, SEEK_END) == -1) {
  perror ("fseek");
  return EXIT_FAILURE;
  }
  long size = ftell (fp);
  if (size == -1) {
  perror ("ftell");
  return EXIT_FAILURE;
  }
  char* buf= (char*)malloc (size + 1);
  if (! buf) {
  perror ("malloc");
  return EXIT_FAILURE;
  }
  if (fseek (fp, 0, SEEK_SET) == -1) {
  perror ("fseek");
  return EXIT_FAILURE;
  }
  if (fread (buf, 1, size, fp)!=size) {
  perror ("fread");
  return EXIT_FAILURE;
  }
  buf[size] = '\0';
  fclose (fp);
  regex_t ex;
  int error = regcomp (&ex,
  "href=\"\\s*\\([^ >\"]*\\)\\s*\"",0);
  if (error) {
  char errInfo[1024];
  regerror (error, &ex, errInfo,
    sizeof (errInfo));
  printf ("regcomp: %s\n",
    errInfo);
  return EXIT_FAILURE;
  }
  char const* html = buf;
  regmatch_t match[2];
  while (regexec (&ex, html, 2, match,
  0) != REG_NOMATCH) {
  html += match[1].rm_so;
  size_t len = match[1].rm_eo -
    match[1].rm_so;
  char* url = (char*)malloc (
    len + 1);
  memcpy (url, html, len);
  url[len] = '\0';
  printf ("%s\n", url);
  free (url);
  html += len + match[0].rm_eo -
    match[1].rm_eo;
  }
  regfree (&ex);
  free (buf);
  return EXIT_SUCCESS;
}

执行结果

20200208180634103.png

相关文章
|
4天前
|
存储 缓存 安全
第二章 HTTP请求方法、状态码详解与缓存机制解析
第二章 HTTP请求方法、状态码详解与缓存机制解析
|
4天前
|
Web App开发 存储 缓存
第八篇 提升网页性能:深入解析HTTP请求优化策略(三)
第八篇 提升网页性能:深入解析HTTP请求优化策略(三)
|
4天前
|
消息中间件 前端开发 JavaScript
第七篇 提升网页性能:深入解析HTTP请求优化策略(二)
第七篇 提升网页性能:深入解析HTTP请求优化策略(二)
|
4天前
|
编解码 前端开发 JavaScript
第六篇 提升网页性能:深入解析HTTP请求优化策略(一)
第六篇 提升网页性能:深入解析HTTP请求优化策略(一)
|
6天前
|
XML Java 数据库
【后台开发】TinyWebser学习笔记(3)HTTP连接与解析
【后台开发】TinyWebser学习笔记(3)HTTP连接与解析
14 4
|
6天前
|
缓存 负载均衡 网络协议
【亮剑】一次完整的HTTP请求的重要性和详细过程
【4月更文挑战第30天】本文介绍了HTTP请求的重要性和详细过程。首先,DNS解析将域名转换为IP地址,通过递归和迭代查询找到目标服务器。接着,TCP三次握手建立连接。然后,客户端发送HTTP请求,服务器处理请求并返回响应。最后,理解这个过程有助于优化网站性能,如使用DNS缓存、HTTP/2、Keep-Alive、CDN和负载均衡等实践建议。
|
6天前
|
前端开发 API UED
AngularJS的$http服务:深入解析与进行HTTP请求的技术实践
【4月更文挑战第28天】AngularJS的$http服务是核心组件,用于发起HTTP请求与服务器通信。$http服务简化了通信过程,通过深入理解和实践,能构建高效、可靠的前端应用。
|
6天前
|
XML JSON 监控
深入解析JMeter HTTP 请求头:实战技巧
在深入研究 JMeter 的过程中,任何涉及性能测试或接口验证的专业人员都会认识到,合理配置HTTP请求头部信息是实现精确测试的关键步骤之一。不同情景下,如数据提交形式的不同(例如 JSON、XML 等),或是需要通过 HTTP 头传递特定的认证信息(如使用 JWT 或 OAuth 2.0 令牌)时,了解如何在 JMeter 中灵活设置请求头显得尤为重要。
|
6天前
|
数据采集 缓存 监控
HTTP与URL基础解析及简单示例实践
HTTP与URL基础解析及简单示例实践
|
6天前
|
安全 数据安全/隐私保护
深入解析:HTTP和HTTPS的三次握手与四次挥手
在这些握手和挥手过程中,双方交换信息,协商参数,建立或关闭连接,以保证数据的可靠传输。HTTPS在此基础上加入了数字证书验证和加密通信,增加了安全性。这些步骤确保了HTTP和HTTPS协议的通信过程的稳定和安全。
125 0

相关产品

  • 云解析DNS
  • 推荐镜像

    更多