这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
前言
今天的所有问答都是和chatgpt进行的
网页被加载的全过程(包括服务器 托管服务器)
-
用户输入网址:用户输入网址,浏览器会把网址发送给 DNS 服务器,用于查找网站的 IP 地址。
-
DNS 服务器查找:DNS 服务器会把查询的结果返回给浏览器。
-
浏览器发出请求:浏览器会把网址对应的 IP 地址发出请求,请求被路由到指定的服务器上。
-
服务器处理请求:服务器接收到浏览器的请求,会对请求的数据进行处理,然后返回 HTML 文件,CSS 文件,JavaScript 文件等网页资源。
-
浏览器解析文件:浏览器接收到服务器返回的文件,会把文件解析,把CSS 文件,JavaScript 文件和图片等资源请求发送给服务器。
-
浏览器渲染网页:浏览器接收到所有资源文件,会把文件进行渲染,生成网页,最终用户可以看到网页。 可以详细介绍一下服务器处理请求吗
服务器处理请求是指,当服务器接收到浏览器的请求后,会对请求的数据进行处理,然后返回 HTML 文件,CSS 文件,JavaScript 文件等网页资源。
具体来说,服务器处理请求的过程有以下几步:
-
解析请求:服务器会把请求报文中包含的参数,如请求方法、URL、协议版本等信息解析出来。
-
调用服务器端程序:根据请求的 URL,服务器会调用相应的服务器端程序,比如 php、asp 等程序。
-
处理请求:服务器会把请求参数传递给服务器端程序,服务器端程序根据请求参数处理请求,比如查询数据库、网络访问等。
-
生成响应:服务器端程序处理完请求后,会返回响应,比如 HTML 文件,CSS 文件,JavaScript 文件等网页资源。
-
返回响应:服务器会把响应发送给浏览器,浏览器接收到响应后就可以渲染网页了。 区分一下托管网站 服务器 服务器程序
托管网站:托管网站是指把网站的文件及数据存放在网络上,客户可以使用网络来访问的服务。
服务器:服务器是一种计算机系统,它负责接收客户端请求,处理请求,并返回响应结果。
服务器程序:服务器程序是一种特定的计算机程序,它运行在服务器上,负责处理客户端请求,并返回响应结果。 如果是 静态网站会调用服务器程序吗
如果是静态网站,服务器会把请求的 HTML 文件,CSS 文件,JavaScript 文件等网页资源直接返回给浏览器,不需要调用服务器程序。 我的云服务器是哪个部分?
你的云服务器就是服务器的一部分,它是指把服务器的计算能力、存储能力和网络资源等部署到云端的服务器,客户可以使用网络访问。
Web框架会起到什么作用呢?
Web框架是一种软件开发技术,它可以帮助开发者快速构建网站及 Web 应用。Web 框架可以提供很多有用的功能,比如路由功能、数据库访问功能、模板功能等,这些功能可以帮助开发者更快速地开发出高质量的 Web 应用。 可以以gin为例 举个例子让我看到他怎么帮助我的吗?
以 Gin 为例,Gin 是一个开源的 Go 语言 Web 框架,它提供了路由功能、数据库访问功能、模板功能等有用的功能。
以路由功能为例,Gin 可以帮助开发者快速构建 Web 应用的路由系统,开发者可以用 Gin 来构建 RESTful 的路由,比如:
// 创建一个 Gin 实例 r := gin.Default() // 处理 GET 请求,返回用户列表 r.GET("/users", func(c *gin.Context) { // 从数据库获取用户列表 users := getUsersFromDatabase() // 把用户列表返回给客户端 c.JSON(200, users) })
// 处理 POST 请求,添加新用户 r.POST("/users", func(c *gin.Context) { // 从请求中获取用户信息 user := getUserFromRequest(c) // 把用户信息保存到数据库 saveUserToDatabase(user) // 把成功响应返回给客户端 c.JSON(200, gin.H{ "message": "success" }) })
// 监听端口,开启服务 r.Run(":8080")
可以看到,Gin 可以帮助开发者快速构建 Web 应用的路由系统,使用 Gin 可以让路由的开发更加简单快捷。 如果我不使用gin 能帮我介绍下上一个例子的实现吗?
如果不使用 Gin,也可以实现上面的例子,可以使用 Go 语言的 net/http 包搭建 Web 服务,然后自己编写处理路由的代码。
以处理 GET 请求为例,可以使用以下代码:
// 创建 http.Handler handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 检查请求方法是否是 GET if r.Method == http.MethodGet { // 从数据库获取用户列表 users := getUsersFromDatabase() // 把用户列表返回给客户端 json.NewEncoder(w).Encode(users) } })
// 监听端口,开启服务 http.ListenAndServe(":8080", handler)
可以看到,不使用 Gin 也可以实现上面的例子,但代码量会比使用 Gin 多很多,而且编写起来也更加复杂。
看起来也不是很臃肿 可以用C++的风格实现上面的功能吗?
可以的,可以使用 C++ 的风格来实现上面的功能,可以使用 C++ 的网络编程库(比如 libcurl)来搭建 Web 服务,然后使用 C++ 来处理路由。 以处理 GET 请求为例, 可以使用以下代码:
// 创建一个C++ http服务器
HttpServer server;
// 处理 GET 请求 server.onGet("/users", [](Request& request, Response& response) {
// 从数据库获取用户列表
auto users = getUsersFromDatabase();
// 把用户列表返回给客户端
response.setBody(users); });
// 监听端口,开启服务
server.listen(8080);
可以看到,可以使用 C++ 的风格来实现上面的功能,这种方式比使用 Go 语言要复杂得多,而且也更加繁琐。
这种方法不是套接字编程吧?可以介绍下区别吗?
答:套接字编程和使用 C++ 的风格来实现 Web 服务器功能之间有很大的区别。 套接字编程(socket programming)是指用 C/C++ 编程语言来编程 TCP/IP 协议族的网络通信,而使用 C++ 的风格来实现 Web 服务器功能则是基于 TCP/IP 协议族的一种应用层的编程,它可以更加方便地处理 HTTP 协议,而不需要额外的套接字编程。
可以简单从底层介绍一下 C++ 中 C++ 的网络编程库 libcurl 是怎么创建的 HttpServer server吗?
答:使用 libcurl 库创建 HttpServer server 时,首先需要初始化一个 libcurl 的句柄,然后使用 curl_easy_setopt 函数来设置 libcurl 的一些参数,比如 URL 地址,HTTP 请求方法等。最后使用 curl_easy_perform 函数来发送 HTTP 请求,然后接收服务器返回的响应数据,并处理响应数据。
libcurl库中 有涉及到套接字吗?
答:是的,libcurl 库中有涉及到套接字,libcurl 使用底层的套接字编程来实现网络通信,它可以创建套接字,发送和接收数据,以及处理网络中的其他相关问题。
据我所知HTTP协议是非连接的吧 为什么也需要使用套接字?
答:HTTP 协议是基于 TCP/IP 协议族的应用层协议,也就是说它是依赖于 TCP/IP 协议族的底层协议来实现的,因此,使用 HTTP 协议时也需要使用套接字编程来实现网络通信。
也就是说 HTTP的信息 也有三次握手吗?
答:是的,HTTP 协议也会发起三次握手,这是为了确保客户端和服务器之间的连接可以正常进行。
哪是什么协议非连接了?我记得有一个?
答:UDP(用户数据报协议)是一种非连接协议,它不会发起三次握手,而是直接发送数据,不管对方是否准备好接收,同时也不会发送确认报文。
不不不 我指的是应用层 有这样的非连接协议吗?
答:是的,应用层也有非连接协议,比如 DNS 协议(域名系统)和 SNMP 协议(简单网络管理协议)都是非连接协议,它们不会发起三次握手,而是直接发送数据,不管对方是否准备好接收,也不会发送确认报文。
HTTP的每个请求都会建立一次三次握手吗 这样不会有很大开销吗?
答:是的,HTTP 的每个请求都会发起三次握手,这样可以确保客户端和服务器之间的连接可以正常进行,但是这样会有一定的开销,比如增大带宽使用,延长响应时间等。
有类似数据库连接池之类的优化吗?
答:是的,有类似数据库连接池之类的优化,可以通过缓存一些常用的 HTTP 请求,来减少每次请求所需要的时间,从而提高效率。
具体的实现呢? 可以举举例子吗?
答:可以举个例子,比如在使用 HTTP 请求来获取一个网页的时候,系统会先检查是否有缓存的网页,如果有,则直接从缓存中获取,这样就可以减少发起三次握手的时间,来提高效率。
参考材料: chatgpt
码风略丑 读者见谅 --2023/2/15