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

目录

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功能

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

 服务代码

#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服务器的截图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

拦截器以及统一功能的实现

目录 引言 实现一个简单的拦截器 拦截器小结 统一访问前缀 统一异常处理 统一返回参数 ControllerAdvice 引言 HandlerInterceptor是Spring MVC框架提供的一个拦截器接口&#xff0c;它用于对请求进行拦截和处理。在Spring MVC中&#xff0c;拦截器可以用于实现一些通用的功能…

OpenCV官方教程中文版 —— 直方图均衡化

OpenCV官方教程中文版 —— 直方图均衡化 前言一、原理二、 OpenCV 中的直方图均衡化三、 CLAHE 有限对比适应性直方图均衡化 前言 本小节我们要学习直方图均衡化的概念&#xff0c;以及如何使用它来改善图片的对比。 一、原理 想象一下如果一副图像中的大多是像素点的像素值…

哪些车企AEB标配率「不及格」

对于汽车智能化来说&#xff0c;基础安全不分高低配。但实际情况&#xff0c;却是另一番景象。 在全球范围&#xff0c;目前不少国家及地区的监管机构正在考虑将AEB&#xff08;紧急制动系统&#xff09;作为乘用车的标配纳入法规&#xff0c;“这是道路安全向前迈出了重要的一…

2023全新TwoNav开源网址导航系统源码 | 去授权版

2023全新TwoNav开源网址导航系统源码 已过授权 所有功能可用 测试环境&#xff1a;NginxPHP7.4MySQL5.6 一款开源的书签导航管理程序&#xff0c;界面简洁&#xff0c;安装简单&#xff0c;使用方便&#xff0c;基础功能免费。 TwoNav可帮助你将浏览器书签集中式管理&#x…

C++中显示构造和隐式构造

截图来源于C primerplus 第六版。

行情分析——加密货币市场大盘走势(10.25)

目前大饼继续上涨&#xff0c;还没有看到震荡盘整的迹象。从MACD日线来看&#xff0c;连续绿色实心柱已经10天。现在有点上涨无力了&#xff0c;而现在入场做空性价比更高&#xff0c;看反弹到33000-32000。如果谨慎点&#xff0c;可以继续等待。 以太目前来看和大饼一样那个也…

Ubuntu OpenLDAP配置笔记

Ubuntu OpenLDAP配置笔记 问题&#xff08;需求&#xff09;LDAP服务端安装slapd和ldap-utils配置域名编辑hosts修改主机名验证增加一个域账号修改用户的密码 Linux桌面加域安装软件验证允许远程账号首次登录时自动创建HOME目录桌面登录 其它问题Ubuntu更新和安装太慢LDAP服务端…

深入了解JavaScript中的AJAX和HTTP请求

在现代Web开发中&#xff0c;AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;和HTTP请求被广泛应用于实现动态交互式网页。本文将深入探讨AJAX的概念、工作原理以及使用方法。 什么是AJAX&#xff1f; AJAX是一种利用JavaScript和HTTP请求与服务器进行异步通信的…

Banana Pi BPI-W3(Armsom W3)RK3588开当板之调试UART

前言 本文主要讲解如何关于RK3588开发板UART的使用和调试方法&#xff0c;包括UART作为普通串口和控制台两种不同使用场景 一. 功能特点 Rockchip UART (Universal Asynchronous Receiver/Transmitter) 基于16550A串口标准&#xff0c;完整模块支持以下功能&#xff1a; 支…

从零开始做一个SDWAN

VPN和SD-WAN的区别 VPN&#xff08;Virtual Private Network&#xff09;和SD-WAN&#xff08;Software-Defined Wide Area Network&#xff09;是两种不同的网络技术&#xff0c;它们在目的、功能和实施方式上有一些重要的区别。 目的和应用场景: VPN&#xff1a;VPN主要用于…

什么是有效种草!900万播放成B站“网红品牌”

- 导语 众所周知&#xff0c;B站早期是二次元小众社区&#xff0c;所以ACG&#xff08;动画、漫画、游戏三者的合称&#xff09;内容一直是B站的核心品类&#xff0c;B站经过多品类内容的摸索和发展&#xff0c;一直到现在成为年轻一代聚集的多元化社区&#xff0c;但ACG内容仍…

AI智能监控平台EasyCVR+无人机方案:实时全景无死角全方面助力山区安防系统新升级

无人机作为高速发展的高科技设备&#xff0c;技术日趋成熟&#xff0c;目前已经被广泛应用于农业、森林防护、医疗、交通物流等等场景。但随着城市化进程的加快&#xff0c;人类对自然环境日益严重的破坏&#xff0c;近十几年来&#xff0c;森林火灾的发生频率和失火严重程度一…

Zabbix出现 404Not FoundThe requested URL /zabbix was not found on this server.

目录 一、问题&#xff1a; 二、原因&#xff1a; 三、解决方法&#xff1a; 一、问题&#xff1a; Not Found The requested URL /zabbix was not found on this server. 二、原因&#xff1a; 未找到 在此服务器上找不到请求的 URL /zabbix。 /etc/httpd/conf.d 目录…

【uniapp】小程序开发7:自定义组件、自动注册组件

一、自定义轮播图组件、自动注册 以首页轮播图组件为例。 1、创建组件文件src/components/my-swipper.vue 代码如下&#xff1a; <template><view><view class"uni-margin-wrap"><swiper class"swiper" circular :indicator-dots…

22 行为型模式-状态模式

1 状态模式介绍 2 状态模式结构 3 状态模式实现 代码示例 //抽象状态接口 public interface State {//声明抽象方法,不同具体状态类可以有不同实现void handle(Context context); }

Golang 数据库操作

文章目录 初始化连接连接池SetMaxOpenConnsSetMaxIdleConnsSetConnMaxIdleTimeSetConnMaxLifetime 查询数据插入数据更新数据删除数据实现账号密码登录功能sqlx的部分用法 首先安装包&#xff1a;Install go get -u github.com/go-sql-driver/mysql // MySQL数据库的包 go get…

单片机中的 _nop_() 延时以及其相关的基础扩展

使用 _nop_() 函数做延时遇到的一些问题 以及对此延伸出的一些需要了解的基本概念 ...... by 矜辰所致 完善文章内容结构&#xff0c;补充指令周期、机器周期等一些基本概念 2023/10/25前言 最近还是继续做着项目&#xff0c;因为在某 8051 内核芯片上使用到了 I…

【MySQL】用户与权限管理

文章目录 一、用户管理1、用户信息表2、创建用户3、删除用户4、修改用户密码 二、权限管理1、MySQL 权限2、给用户授权3、回收用户权限 一、用户管理 之前为了方便&#xff0c;我们学习 MySQL 时统一使用的都是 root 账号进行登录&#xff0c;但在实际的开发场景中必然是需要进…

opencalib中lidar2camera安装记录

目录 一、opencalib安装 二、lidar2camera的安装 三、测试运行 四、出现过的问题 一、opencalib安装 代码地址&#xff1a;https://github.com/PJLab-ADG/SensorsCalibration/blob/master/README.md # pull docker image sudo docker pull scllovewkf/opencalib:v1 # Aft…

RISC-V架构——中断委托和中断注入

1、中断委托 1.1、中断委托的作用 &#xff08;1&#xff09;默认情况下&#xff0c;所有的陷入&#xff08;中断和异常&#xff09;都是在M模式下处理&#xff0c;然后再返回到发生陷入前的模式&#xff1b; &#xff08;2&#xff09;所有陷入都在M模式处理会涉及到模式切换…