域名解析及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

目录
打赏
0
0
0
0
16
分享
相关文章
深度解析HTTP协议从版本0.9至3.0的演进和特性。
总的来说,HTTP的演进是互联网技术不断发展和需求日益增长的结果。每一次重要更新都旨在优化性能,增进用户体验,适应新的应用场景,而且保证了向后兼容,让互联网的基础架构得以稳定发展。随着网络技术继续进步,我们可以预期HTTP协议在未来还会继续演化。
287 0
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
301重定向实现原理全面解析:从HTTP协议到SEO最佳实践
301重定向是HTTP协议中的永久重定向状态码,用于告知客户端请求的资源已永久移至新URL。它在SEO中具有重要作用,能传递页面权重、更新索引并提升用户体验。本文详解其工作原理、服务器配置方法(如Apache、Nginx)、对搜索引擎的影响及最佳实践,帮助实现网站平稳迁移与优化。
308 68
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
95 10
SSL证书验证全攻略:DNS/HTTP/手动解析怎么选?
SSL证书在网络安全中至关重要,1Panel提供三种验证方式:DNS验证、HTTP验证和手动解析。DNS验证便捷,适合CDN网站;HTTP验证快速,需服务器在线;手动解析灵活,但操作复杂。根据需求选择合适确认方式,定期检查证书状态。
515 2
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
135 1
|
3月前
|
Go
在golang中发起http请求以获取访问域名的ip地址实例(使用net, httptrace库)
这只是追踪我们的行程的简单方法,不过希望你跟着探险家的脚步,即使是在互联网的隧道中,也可以找到你想去的地方。接下来就是你的探险之旅了,祝你好运!
145 26
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
238 3
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
383 5
|
4月前
|
网络问题解析:如何解决CondaHTTPError HTTP 000 CONNECTION FAILED错误。
以上就是斯诺普为你准备的解决Conda出现HTTP连接错误的手术室。希望这辆小车可以顺利驶出棘手的泥潭,再次在自由的大路上疾驰。一切的尝试和努力,只为更好的探索与开发。
178 17

相关产品

  • 云解析DNS
  • 推荐镜像

    更多
  • DNS
  • AI助理
    登录插画

    登录以查看您的控制台资源

    管理云资源
    状态一览
    快捷访问

    你好,我是AI助理

    可以解答问题、推荐解决方案等