lv8 嵌入式开发-网络编程开发 20 域名解析与http服务实现原理

news2024/12/24 0:34:14

目录

1 域名解析

2 如何实现万维网服务器?

2.1 HTTP 的操作过程

2.2 万维网服务器实现


1 域名解析

域名解析gethostbyname函数 

主机结构在 <netdb.h> 中定义如下:

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:中的第一个地址,以实现向后兼容性

示例

#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;
}

实现效果

2 如何实现万维网服务器?

2.1 HTTP 的操作过程

HTTP 规定:在 HTTP 客户与 HTTP 服务器之间的每次交互,都由一个 ASCII 码串构成的请求和一个类似的通用互联网扩充,即“类MIME (MIME-like)”的响应组成。

HTTP 报文通常都使用 TCP 连接传送。

 http连接过程

 html解释型语言

<html>
<head><title>home</title></head>
<body>
<center><h1>Hello World!</h1></center>
<hr><center>nginx</center>
</body>
</html>

 打开home.html(firefox ./home.html)

2.2 万维网服务器实现

nc命令实现步骤

  • 打开终端,nc <本机ip> 80
  • 打开游览器访问本机ip
  • 在终端输入以下内容
HTTP/1.1 200 OK
Content-Type: text/html

<html>
<head><title>home</title></head>
<body>
<center><h1>Hello World!</h1></center>
<hr><center>nginx</center>
</body>
</html>

代码实现步骤

  • 准备好http文件
  • 准备好html文件
  • 创建TCP socket
  • 实现client hanlde功能
<html>
<head>
<title>server name</title>
<meta charset="utf-8">
</head>
<body>
<body>
<h1>文档标题</h1>
<p>Hello World!</p>
</body>
</body>
</html>
HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

#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并且信号中断
	if(ret < 0){
		perror("recv");
		exit(0);
	}else if(ret == 0){
		close(newfd);
		return 0;
	}else{
		printf("=====================================\n");
		printf("%s", buf);
		fflush(stdout);
	}

	bzero(buf, ret);
	file_fd = open(HTTPFILE, O_RDONLY);   //http文件
	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);

	bzero(buf, ret);
	file_fd = open(HTMLFILE, O_RDONLY);   //html文件
	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;
}

 3 练习

1.模拟实现http服务器,并使用浏览器访问。提交浏览器访问你http服务器的截图

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

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

相关文章

MIT 6.824 -- Cache Consistency -- 11

MIT 6.824 -- Cache Consistency -- 11 引言严峻挑战锁服务缓存一致性问题案例演示优化 原子性问题故障恢复问题log内容故障恢复 小结 课程b站视频地址: MIT 6.824 Distributed Systems Spring 2020 分布式系统 推荐伴读读物: 极客时间 – 大数据经典论文解读DDIA – 数据密集…

网工记背命令(7)----静态路由(负载分担,主备备份)

1.静态路由负载分担 如图所示&#xff0c;属于不同网段的主机通过几台 Switch 相连&#xff0c;要求不配置动态路由协议&#xff0c;使不同网 段的任意两台主机之间能够互通&#xff0c;从拓扑图中可以看出&#xff0c;从 PCA 到 PCC 有两条路径可以过去&#xff0c;分别是 PC…

第三章 内存管理 十三、页面置换算法(最佳置换算法、先进先出置换算法、最近最久未使用置换算法、时钟置换算法、改进型的时钟置换算法)

目录 一、定义 二、分类 1、最佳置换算法 / 最远置换算法&#xff08;OPT&#xff0c;Optimal): 1.1、定义&#xff1a; 1.2、例子&#xff1a; 2、先进先出置换算法(FIFO&#xff09;: 2.1、定义&#xff1a; 2.2、实现方法&#xff1a; 2.3、例子&#xff1a; 3、最…

【Pillow库的内涵】01/3 进行基本图像操作

一、说明 Pillow 具有被 Python 社区广泛使用的优势&#xff0c;并且它不像其他一些图像处理库那样具有陡峭的学习曲线。应用PIL库的Image对象&#xff0c;益处很多&#xff0c;首先它可以处理网上URL文件&#xff0c;其次&#xff0c;图片可以方面转化成int32、64或float类型&…

蓝桥杯 (猜生日、棋盘放麦子、MP3储存 C++)

思路&#xff1a; 1、用循环。 2、满足条件&#xff0c;能整除2012、3、12且month等于6、day<30 #include<iostream> using namespace std; int main() {for (int i 19000101; i < 20120312; i){int month i / 100 % 100;int day i % 100;if (i % 2012 0 &…

互联网Java工程师面试题·Java 面试篇·第二弹

目录 15、什么是不可变对象&#xff08;immutable object&#xff09;&#xff1f;Java 中怎么创建一个不可变对象&#xff1f; 16、我们能创建一个包含可变对象的不可变对象吗&#xff1f; 17、Java 中应该使用什么数据类型来代表价格&#xff1f; 18、怎么将 byte 转换为 Str…

图论03-【无权无向】-图的深度优先遍历-路径问题/检测环/二分图

文章目录 1. 代码仓库2. 单源路径2.1 思路2.2 主要代码 3. 所有点对路径3.1 思路3.2 主要代码 4. 路径问题的优化-提前结束递归4.1 思路4.2 主要代码 5. 检测环5.1 思路5.2 主要代码 5. 二分图5.1 思路5.2 主要代码5.2.1 遍历每个联通分量5.2.2 递归判断相邻两点的颜色是否一致…

192:最近的系列思考2/犬岛APP 的使用理解

最近的一些契机&#xff0c;导致一些思考&#xff1a; ​ * 与产品经理意志相悖的产品* 与最初的设计定位不匹配的产品社交大牛的APP一上线就引来诸多关注&#xff0c;作为总设计的纯大大非常简明扼要的说明了这个APP的定位&#xff1a;给内涵&#xff08;含&#xff09;有趣的…

图论04-【无权无向】-图的广度优先遍历

文章目录 1. 代码仓库2. 广度优先遍历图解3.主要代码4. 完整代码 1. 代码仓库 https://github.com/Chufeng-Jiang/Graph-Theory 2. 广度优先遍历图解 3.主要代码 原点入队列原点出队列的同时&#xff0c;将与其相邻的顶点全部入队列下一个顶点出队列出队列的同时&#xff0c;将…

布尔盲注知识点

概念&#xff1a;布尔盲注一般适用于页面没有回显字段(不支持联合查询)&#xff0c;且web页面返回True 或者 false&#xff0c;构造SQL语句&#xff0c;利用and&#xff0c;or等关键字来其后的语句 true 、 false使web页面返回true或者false&#xff0c;从而达到注入的目的来获…

Python---练习:while循环案例:猜数字

需求&#xff1a; 计算机从1 ~ 10之间随机生成一个数字&#xff0c;然后提示输入数字&#xff0c;如果我们输入的数字与随机数相等&#xff0c;则提示恭喜你&#xff0c;答对了。如果输入的数字比随机数大&#xff0c;则提示&#xff0c;猜大了。反之&#xff0c;则提示猜小了…

晶振与晶体

文章目录 基础知识无源晶振 & 有源晶振 博文链接 基础知识 无源晶振 & 有源晶振 博文链接 晶振原理解析

在Vue中使用Mock.js虚拟接口数据实例详解

在Vue项目中使用Mock.js可以方便地模拟接口数据&#xff0c;用于前端开发和测试。Mock.js是一个生成随机数据的库&#xff0c;可以帮助我们快速构建虚拟接口数据。在本文中&#xff0c;我将通过一个实例来详细讲解在Vue中使用Mock.js虚拟接口数据的方法。 首先&#xff0c;我们…

H5前端开发——事件处理

H5前端开发——事件处理 在H5前端开发中,事件处理是非常重要的一部分。通过事件处理,可以实现对用户操作的响应和交互。以下是几种常见的事件处理方式: HTML事件处理: 在HTML标签上直接设定事件处理函数,如<button onclick="myFunction()">点击我</bu…

【每周一测】Java阶段三第二周学习

目录 1、以下哪个过程可以创建Class对象? 2、下列switch代码段输出结果是&#xff08;&#xff09; 3、redis的数据类型 4、⭐以下关于Servlet生命周期说法错误的是&#xff08; &#xff09; 5、⭐下面有关SPRING的事务传播特性&#xff0c;说法错误的是&#xff1f; 6…

自然语言处理---huggingface平台使用指南

1 huggingface介绍 Huggingface总部位于纽约&#xff0c;是一家专注于自然语言处理、人工智能和分布式系统的创业公司。他们所提供的聊天机器人技术一直颇受欢迎&#xff0c;但更出名的是他们在NLP开源社区上的贡献。Huggingface一直致力于自然语言处理NLP技术的平民化(democr…

数据结构 MapSet(搜索)

数据结构 Map&Set(搜索) 文章目录 数据结构 Map&Set(搜索)1. 搜索树1.1 概念1.2 初始构建1.3 操作-插入1.4 操作-查找1.5 操作-删除1.6 性能分析 2. 搜索介绍2.1 概念及场景2.2 模型 3. Map的使用3.1 关于Map的说明3.2 关于Map.Entry<K, V>的说明3.3 Map的常用方…

Hadoop3教程(三十一):(生产调优篇)异构存储

文章目录 &#xff08;157&#xff09;异构存储概述概述异构存储的shell操作 &#xff08;158&#xff09;异构存储案例实操参考文献 &#xff08;157&#xff09;异构存储概述 概述 异构存储&#xff0c;也叫做冷热数据分离。其中&#xff0c;经常使用的数据被叫做是热数据&…

寻找Windows API 原始字节(x64dbg)

首先我们将我们的木马移入x64dbg 第一种方法 通过命令寻找 disasm CreateRemoteThreadEx第二种方法 将调试器附加到kernelbase.dll后转到符号选项卡&#xff0c;最后&#xff0c;在搜索栏中&#xff0c;我们可以搜索CreateRemoteThreadEx函数并双击它以获取下列&#xff1a…

深度学习---神经网络基础

深度学习概述 机器学习是实现人工智能的一种途径&#xff0c;深度学习是机器学习的一个子集&#xff0c;深度学习是实现机器学习的一种方法。与机器学习算法的主要区别如下图所示&#xff1a; 传统机器学习算术依赖人工设计特征&#xff0c;并进行特征提取&#xff0c;而深度学…