【网络编程开发】16.域名解析与http服务器实现原理

16.域名解析与http服务器实现原理

文章目录

  • 16.域名解析与http服务器实现原理
    • gethostbyname 函数
    • HTTP的操作过程
    • 实现http
      • home.html
      • http-head.txt
      • server.c

gethostbyname 函数

  1. 原型

    #include <netdb.h>
    struct hostent *gethostbyname(const char *hostname);
    
  2. 功能:获取主机名对应的IP地址

  3. 参数hostname:要查询的主机名。

  4. 返回值

    • 成功时,返回一个指向hostent结构的指针。
    • 失败时,返回NULL。
  5. 注意:使用完该函数后记得使用endhostent函数进行销毁,清理缓冲区。

  6. struct hostent

    • struct hostent {char  *h_name;  /* 官方域名 */char **h_aliases;  /* 别名*/int    h_addrtype;  /* 地址族(地址类型) */int    h_length;  /* 地址长度 */
      char **h_addr_list;  /* 地址列表 */
      }
      #define h_addr h_addr_list[0] /* 实现向后兼容性 */
      
    • h_name :主机的正式名称

    • h_aliases:主机的备用名称数组,以 NULL 结尾指针

    • h_addrtype:地址类型;(AF_INETAF_INET6

    • h_length:地址的长度(以字节为单位)

    • h_addr_list:指向主机网络地址的指针数组(按网络字节顺序),由 NULL 指针终止

    • h_addr h_addr_list:中的第一个地址,以实现向后兼容性

  7. 示例

    #include <stdio.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    #include <arpa/inet.h>int main(int argc, char *argv[])
    {int i;
    /*检查参数*/if(argc < 2){printf("%s <host name>\n", argv[0]);exit(0);}
    /*将域名赋值给结构体*/struct hostent *host = gethostbyname(argv[1]);/*打印结构体的内容*/for(i = 0; host->h_aliases[i] != NULL; i++){printf("%s\n", host->h_aliases[i]);}printf("Address type:%s\n",host->h_addrtype == AF_INET ? "AF_INET":"AF_INET6");for(i = 0; host->h_addr_list[i] != NULL; i++){printf("IP address %d:%s\n", i, inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));}endhostent();//关闭主机信息文件return 0;
    }
    

    运行程序:./test www.baidu.com

    在这里插入图片描述

HTTP的操作过程

在这里插入图片描述

  1. DNS解析:当用户在浏览器中输入URL或点击链接时,浏览器首先需要将域名转换为对应的IP地址。这一过程称为DNS解析。浏览器会向DNS服务器查询该域名对应的IP地址。
  2. 建立TCP连接:获取到IP地址后,浏览器会与服务器建立TCP连接,这一过程涉及到TCP协议的三次握手。这是为了确保数据能够准确、有序地在网络中传输。
  3. 封装HTTP请求数据包:一旦TCP连接建立成功,浏览器会封装一个HTTP请求数据包,其中包含了请求行、请求头和请求体等信息。
  4. 发送HTTP请求:随后,浏览器通过已经建立的TCP连接,向服务器发送HTTP请求。这个请求可能包含对网页文档的请求,或是对图片、CSS、JavaScript等资源的请求。
  5. 服务器处理请求:服务器接收到HTTP请求后,会根据请求的内容进行处理。这包括读取请求的资源、执行相应的脚本等操作。
  6. 服务器返回响应:处理完请求后,服务器会返回一个HTTP响应,其中包括了状态码、响应头和响应体等信息。状态码告诉客户端请求是否成功,或者遇到了何种错误。
  7. 浏览器解析HTML:收到响应后,浏览器开始解析HTML代码,并构建DOM树。同时,浏览器会根据HTML中的标签和属性,请求必要的资源文件,如CSS样式表、JavaScript脚本以及图片等。
  8. 浏览器渲染页面:在取得并解析所有资源文件后,浏览器开始渲染页面。这个过程包括计算每个元素的位置和样式,最终将页面呈现出来。
  9. 关闭TCP连接:一旦服务器发送了请求的数据,通常会主动关闭TCP连接。但在某些情况下,如果响应头信息中包含Connection:keep-alive,则连接仍然保持打开状态,以便后续在同一连接上发送更多请求

实现http

home.html

<html>
<head>
<title>server name</title>
<meta charset="utf-8">
</head>
<body>
<body>
<h1>文档标题</h1>
<p>Hello World!</p>
</body>
</body>
</html>

http-head.txt

HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

server.c

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <strings.h>#define PORT 80
#define BACKLOG 5
#define HTTPFILE "http-head.txt"
#define HTMLFILE "home.html"int ClientHandle(int newfd);int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr;/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}int opt = 1;if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &opt, sizeof(opt) ))perror("setsockopt");addr.sin_family = AF_INET;addr.sin_port = htons(PORT);addr.sin_addr.s_addr = 0;/*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, NULL, NULL);if(newfd < 0){perror("accept");exit(0);}ClientHandle(newfd);close(fd);return 0;
}int ClientHandle(int newfd){int file_fd = -1;char buf[BUFSIZ] = {};int ret;
/*接收数据*/do {ret = recv(newfd, buf, BUFSIZ, 0);}while(ret < 0 && errno == EINTR);//如果接收到的数据个数小于0,或者错误为非阻塞时未收到数据的标志EINTRif(ret < 0){perror("recv");exit(0);}else if(ret == 0){//客户端主动结束close(newfd);return 0;}else{printf("=====================================\n");printf("%s", buf);fflush(stdout);//刷新缓冲区}/*读取文件HTTPFILE的内容并发送*/bzero(buf, ret);file_fd = open(HTTPFILE, O_RDONLY);if(file_fd < 0){perror("open");exit(0);}ret = read(file_fd, buf, BUFSIZ);printf("%s\n", buf);send(newfd, buf, ret, 0);close(file_fd);/*读取文件HTMLFILE的内容并发送*/bzero(buf, ret);file_fd = open(HTMLFILE, O_RDONLY);if(file_fd < 0){perror("open");exit(0);}ret = read(file_fd, buf, BUFSIZ);printf("%s\n", buf);send(newfd, buf, ret, 0);close(file_fd);close(newfd);return 0;
}
  1. 查看ip地址 ifconfig
    在这里插入图片描述

  2. 运行程序 sudo ./server

  3. 打开浏览器输入ip地址

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/29693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技巧|手机上看SwanLab实验的两种方法

什么是SwanLab? SwanLab是一个深度学习实验管理与训练可视化工具&#xff0c;由西安电子科技大学创业团队打造&#xff0c;融合了Weights & Biases与Tensorboard的特点&#xff0c;可以记录整个实验的超参数、指标、训练环境、Python版本等&#xff0c;并可视化图表&…

google chrome浏览器安装crx插件Jam

先上一张图&#xff1a; Jam是bug报告生成插件 1、在地址栏中输入chrome://extensions/&#xff0c;然后回车。 2、将下载好的crx插件&#xff0c;直接拖到里面就可以完成安装工作了。 3、测试了一下jam插件&#xff0c;发现直接没有响应。 4、点击【移除】直接可以删除插件…

这四个有意思的工具,很香

提醒英雄 提醒英雄应用是一款能够帮助用户彻底解决健忘症的应用程序。该应用创建的事项会完全同步到通知中心&#xff0c;并且持续保持在锁屏界面上&#xff0c;只要打开手机&#xff0c;用户就会看到之前设置的提醒事项。这种设计确保了用户在任何时候都能及时收到提醒&#…

YOLOv10改进 | 注意力篇 | YOLOv10引入Polarized Self-Attention注意力机制

1. Polarized Self-Attention介绍 1.1 摘要:像素级回归可能是细粒度计算机视觉任务中最常见的问题,例如估计关键点热图和分割掩模。 这些回归问题非常具有挑战性,特别是因为它们需要在低计算开销的情况下对高分辨率输入/输出的长期依赖性进行建模,以估计高度非线性的像素语…

JavaFX DatePicker

JavaFX DatePicker允许从给定日历中选择一天。DatePicker控件包含一个带有日期字段和日期选择器的组合框。JavaFX DatePicker控件使用JDK8日期时间API。 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.DatePicker; import j…

004-配置交换机ssh远程登录

配置交换机ssh远程登录 注意事项 要远程的本机电脑必须与该交换机在同一个网段&#xff0c;以下实验在172.16.12段下模拟&#xff0c;本地ip设置为172.16.12.10&#xff0c;交换机的ip设置为172.16.12.254 将密码设置为明文&#xff08;simple&#xff09;是不安全的&#x…

C++实时检测耳机的插入与拔出(附源码)

目录 1、实现继承于IMMNotificationClient接口类的CMMNotificationClient类,实时感知音频设备变化的通知事件 2、在CMMNotificationClient的构造函数中初始化多媒体设备COM接口,设置回调类指针 3、通过获取音频设备接口下外设的KSJACK_DESCRIPTION 信息判断耳机的连接状态…

猫头虎分享已解决Bug || 前端领域技术问题解析

原创作者&#xff1a; 猫头虎 作者微信号&#xff1a; Libin9iOak 作者公众号&#xff1a; 猫头虎技术团队 更新日期&#xff1a; 2024年6月6日 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &…

从老花眼开始

三年前&#xff0c;博主的的火眼金睛开始老花了&#xff0c;表现就是看近处看不清了。人眼对可视距离的标准可以定义为&#xff1a;看手机为近距离&#xff0c;看电脑为中距离&#xff0c;看电视为中距离&#xff0c;看红绿灯为远距离。老花眼就是戴近视眼镜直接看手机看不清了…

聆思CSK6大模型+AI交互多模态开源SDK介绍

视觉语音大模型 AI 开发套件( CSK6-MIX )是围绕 CSK6011A 芯片设计的具备丰富语音图像功能与硬件外设的开发板&#xff0c;采用具备丰富组件生态的 Zephyr RTOS作为操作系统&#xff0c;官方提供了十几种开源SDK&#xff0c;包含大模型语音交互、大模型拍照识图、文生图、人脸识…

如何在不同的操作系统中查看路由器的IP地址?这里有详细步骤

如果你曾经需要访问路由器的设置页面来进行一些配置更改,你知道你需要路由器的IP地址才能访问。如果你忘记了这个IP地址是什么,下面是如何在几乎所有平台上找到它的。 为什么路由器的IP很有用 在网络世界中,默认网关是一个IP地址,当流量被发送到当前网络之外的目的地时,…

国能数智集团侧交付中心经理曲明志受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 国能数智科技开发&#xff08;北京&#xff09;有限公司智能电力业务部总监、集团侧交付中心经理、公司项目经理协会会长曲明志先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“运营类项目建设经验分享”。大会将于6月…

工业边缘计算网关在机械制造企业中的应用-天拓四方

随着信息技术的不断发展&#xff0c;工业领域对数据处理和分析的需求日益增长。工业边缘计算网关作为一种新型技术&#xff0c;正逐渐成为工业数字化转型的关键驱动力。本文将通过一个具体案例阐述工业边缘计算网关在工业中的应用&#xff0c;以及其为工业生产带来的显著效益。…

Anvil Empires/铁砧帝国操作没反应、频繁掉线怎么办?

Anvil Empires是一款多人在线游戏&#xff0c;且规模非常大&#xff01;玩家需要在持续的在线世界中与成千上万的玩家一起发动战争。目前自定义服务器技术可以使多达 1000 名玩家能够在大规模的实时战斗&#xff0c;且战斗是由玩家在开放世界沙盒中有机地煽动的&#xff0c;所以…

图论之岛屿系列

图论之岛屿系列 形成模板进行学习&#xff0c;加快学习效率 深度优先遍历 # 可以直接改原始grid的采用直接改的方案来完成修改&#xff0c;减少了内存开支 def dfs(self, grid, i, j):if i < 0 or j < 0 or i > len(grid) or j > len(grid[0]) or grid[i][j] &…

传统车牌识别

主要参考&#xff1a;https://blog.csdn.net/qq_40784418/article/details/105586644 其它介绍&#xff1a; https://blog.csdn.net/great_yzl/article/details/120127962 https://blog.csdn.net/onepunch_k/article/details/115480904 cv2.matchTemplate https://docs.ope…

有个网友问Webview2如何另存为mhtml

有个网友问Webview2如何另存为mhtml 。俺查了一下&#xff0c;Webview2没有直接的saveas函数。然后我查到 之后我就使用 webview2 capture 这2个关键字去查询&#xff0c;果然搜到了 一段代码 然后我把这段代码 改成成C#的&#xff0c; string data await webView21.CoreWebV…

学会这几点,轻松制作引人入胜的电子期刊

随着数字化时代的到来&#xff0c;电子期刊已经成为了信息传播的重要载体。它以方便快捷、形式多样、互动性强等特点&#xff0c;受到了广泛的欢迎。那么&#xff0c;如何制作一份引人入胜的电子期刊呢&#xff1f;下面就来为大家分享几点制作电子期刊的小技巧。 1.选择合适的制…

你为什么学习c++?

C 是几乎所有现代面向对象语言的鼻祖&#xff08;注意是现代面向对象语言&#xff0c;还有一个“古代”面向对象&#xff0c;思想是消息传递而不是封装、继承与多态&#xff0c;Objective-C 就是消息传递的面向对象语言&#xff09;。刚好我有一些资料&#xff0c;是我根据网友…

vue2动态横条图(横条图样式定时切换)

每次切换成新图后会清除定时器和图&#xff08;重新加载&#xff0c;否则要么会重复加载定时器。清除定时器之后要先调用一次index为0的数据&#xff09; 数据样例 acrossBarDatas:{data: ["80", "80"],sunffix: [单位, "单位"],title: "标…