【计算机系统导论】7.5 服务器设计

服务器设计与实现,可以自己动手与验证


实际网络的不可靠性

  • 分布式消息传递(可靠性与不可靠性、阻塞与无阻塞)
  • 远程过程调用(参数传递、表示、客户端服务器绑定、同步和异步、面向对象机制)

一次网络浏览背后

在浏览器中输入 www.baidu.com 后执行的全部过程

  现在假设如果我们在客户端(客户端)浏览器中输入http://www.baidu.com,而baidu.com为要访问的服务器(服务器),下面详细分析客户端为了访问服务器而执行的一系列关于协议的操作:

  1)客户端浏览器通过DNS解析到www.baidu.com的IP地址220.181.27.48,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到220.161.27.48,然后通过TCP进行封装数据包,输入到网络层。

  2)在客户端的传输层,把HTTP会话请求分成报文段,添加源和目的端口,如服务器使用80端口监听客户端的请求,客户端由系统随机选择一个端口如5000,与服务器进行交换,服务器把相应的请求返回给客户端的5000端口。然后使用IP层的IP地址查找目的端。

  3)客户端的网络层不用关系应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,不作过多的描述,无非就是通过查找路由表决定通过那个路径到达服务器。

  4)客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用ARP的请求应答交换的IP数据包现在就可以传输了,然后发送IP数据包到达服务器的地址。

自己动手做

语言实现简单服务器

使用“网络实用工具”追踪信息到达的路径
您通过互联网发送的信息通常会经过其他电脑,然后才到达最终目的地。

使用“网络实用工具”来跟随信息穿行于由电脑组成的网络时所经过的路径。

打开“网络实用工具”。

点按 Traceroute。

键入最终目的地的域名或 IP 地址,然后点按“跟踪”按钮。

若要获得解释结果的帮助,或者若要查看如何使用底层 traceroute 命令微调排除故障,请打开“终端”(位于“应用程序”文件夹的“实用工具”文件夹中),然后在命令行键入 man traceroute:

结合不同的命令复习所有的概念

epoll 的原理

Socket 套接字

什么是Socket?

Socket又称之为“套接字”,是系统提供的用于网络通信的方法。它的实质并不是一种协议,没有规定计算机应当怎么样传递消息,只是给程序员提供了一个发送消息的接口,程序员使用这个接口提供的方法,发送与接收消息。
Socket描述了一个IP、端口对。它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息。所以,Socket一定包含了通信的双发,即客户端(Client)与服务端(server)。
Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

Socket的通信过程?

每一个应用或者说服务,都有一个端口。比如DNS的53端口,http的80端口。我们能由DNS请求到查询信息,是因为DNS服务器时时刻刻都在监听53端口,当收到我们的查询请求以后,就能够返回我们想要的IP信息。所以,从程序设计上来讲,应该包含以下步骤:
1)服务端利用Socket监听端口;
2)客户端发起连接;
3)服务端返回信息,建立连接,开始通信;
4)客户端,服务端断开连接。

SOCKET原理

套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应 用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

建立socket连接

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发 给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
这里写图片描述

TCP/IP,SOCKET,HTTP,TCP,UDP联系和区别

http协议 对应于应用层
tcp协议 对应于传输层
ip协议 对应于网络层

三者本质上没有可比性。
HTTP协议是基于TCP连接的。
TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。
我们在传输数据时,可以只使用传输层(TCP/IP),但是那样的话,由于没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用应用 层协议,应用层协议很多,有HTTP、FTP、TELNET等等,也可以自己定义应用层协议。WEB使用HTTP作传输层协议,以封装HTTP文本信息, 然后使用TCP/IP做传输层协议将它发送到网络上。
Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

HTTP连接

HTTP协议即超文本传送协议(HypertextTransfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。
由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请 求。通常的做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复, 表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

TCP连接

要想明白Socket连接,先要明白TCP连接。手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
建立起一个TCP连接需要经过“三次握手”:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主 动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客 户端交互,最终确定断开)

TCP 与 UDP

TCP (传输控制协议)

  • 建立连接, 行程传输数据的通道
  • 在连接中进行大数据传输(数据大小不受限制)
  • 通过三次握手完成大连接, 是可靠协议, 安全送达
  • 必须建立连接, 效率会稍低
    UDP (用户数据报协议)
  • 将数据及源和目的封装成数据包中, 不需要建立连接
  • 每个数据报的大小限制在64K之内
  • 因为无需连接, 因此是不可靠协议
  • 不需要建立连接, 速度快

Socket连接与TCP连接

创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

Socket连接与HTTP连接

由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网 络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数 据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求, 不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

服务器架构

Linux 网络编程——并发服务器的三种实现模型 http://blog.csdn.net/tennysonsky/article/details/45671215

自己动手开发一个 Web 服务器(一)https://linux.cn/article-6815-1.html
自己动手开发一个 Web 服务器(二)https://linux.cn/article-6816-1.html
自己动手开发一个 Web 服务器(三)https://linux.cn/article-6817-1.html

HTTP 代理原理及实现(一)https://imququ.com/post/web-proxy.html
HTTP 代理原理及实现(二)https://imququ.com/post/web-proxy-2.html

https://github.com/codercheng/sparrow

http://www.cse.psu.edu/~djp284/cmpsc311-s14/slides/29-networking.pdf

网络空间的心跳 https://www.zhihu.com/roundtable/cyberhack

简短总结

我们经常会听到「TCP/IP 协议」这个名词,从字面上看,有人会认为它专指 TCP 和 IP 两种协议。实际上大多数情况,TCP/IP 协议指的是整个网际协议族(Internet Protocol Suite),是利用 IP 协议进行通讯的其他协议统称。TCP/IP 包含的协议众多,还有一个分层模型。相比较 OSI 模型,TCP/IP 的分层更简单,从下到上分别为:物理层、数据链路层、网络层、传输层和应用层。
IP(Internet Protocol)属于网络层协议,负责联网主机之间的路由选择和寻址。IPv4 中的 4 指的是 TCP/IP 协议的第 4 个版本,直到这个版本,IP 协议才单独拆出来,所以并没有单独的 IPv1 - IPv3。而 IPv5 分给了一个没什么进展的试验性协议,所以下一个版本的 IP 协议变成了 IPv6。
TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是整个 TCP/IP 协议中最重要的两个传输层协议。TCP 是面向连接的、可靠的流协议;UDP 是不具有可靠性的数据报协议。后面可以看到,对可靠性要求比较高的上层协议一般会基于 TCP;而对高速传输和实时性有较高要求的上层协议一般会基于 UDP。
介绍完比较低层的 IP、TCP 和 UDP 之后,下面看几个浏览器中常见的应用层协议。
HTTP 与 WebSocket
HTTP 协议是浏览器需要用到的最重要的网络协议,它包括很多版本,例如最常见的 HTTP/1.1,刚刚发布的 HTTP/2,还有 Google 实现的过渡版本 SPDY 等等。本文不讨论 HTTP 的细节以及各版本之间的差异,只打算列出 HTTP 与其他协议 / 应用之间的关系,见下图:
+————-+————-+————–+
| XHR | SSE | WS |
+————-+————-+——+ +
| HTTP | |
+———————————-+——-+
| TLS * |
+——————————————+
| TCP |
+——————————————+
| IP |
+——————————————+
从上图可以看出 HTTP 是在 TCP 之上实现的,所以 HTTP 中并不需要关注数据传输的可靠性,类似于顺序控制、重发这样的机制在传输层已经有了。同时,HTTP 也拥有 TCP 的一些缺点,给 WEB 性能优化带来挑战。
XHR(XmlHTTPRequest)和 SSE(Server-Sent Events)都是浏览器提供的数据交互功能,它们的本质都还是 HTTP。XHR 是 Ajax 技术的核心,大家都很熟,这里略过不讨论;SSE 概念还算新,多说几句。我们知道 HTTP 只能由客户端发起请求,再由服务端响应。SSE 也是这样,只不过服务端会保持住这个 HTTP 连接,多次发送响应,不像平时发送完响应就结束了。实际上,很早之前在 WebIM 中类似的 HTTP 长连接技术就已经很盛行了,有兴趣的同学可以看下这篇八年前的文章:Comet:基于 HTTP 长连接的「服务器推」技术。
既然 XHR 和 SSE 本质都是 HTTP 连接,所以 HTTP 协议中一些常见概念,例如请求方式(GET、POST 等),请求响应头部(Cookie、内容编码、传输编码、缓存等)等等,依然存在。
而 WS(WebSocket)是直接基于 TCP 实现的,HTTP 协议中的那些概念都不复存在。需要注意的是,从前面图表中可以看出,它还是依赖于 HTTP,这是因为 WebSocket 握手利用了 HTTP 的 Upgrade 机制。一旦握手完成,后续数据传输就直接在 TCP 上完成。浏览器中新协议借助 HTTP 作为引导,是一个较为普遍的做法。
TLS(Transport Layer Security,传输层安全),作用是保证数据在传输过程中的完整性和保密性,属于可选项。启用了 TLS 之后,HTTP 协议的 URL 前缀需要由 http:// 改成 https://;WebSocket 协议的 URL 前缀需要由 ws:// 改成 wss://。
DNS
DNS(Domain Name System),就是大家熟知的域名解析服务,提供了从域名到 IP 的转换。浏览器中大部分网络交互都会使用域名,而传输层协议需要的是 IP,所以 DNS 是基础。
+——————————-+
| DNS |
+——————————-+
| TCP | UDP |
+—————+—————+
| IP |
+——————————-+
DNS 服务默认使用 UDP 协议获得查询结果,通常仅当结果超过 512 字节或者进行 DNS 服务器同步时才会使用 TCP 协议。这是因为 DNS 的使用非常频繁,又是基础,响应速度是优先需要考虑的。使用 UDP 可以满足速度上的要求,但同时也引入了类似于「DNS 缓存投毒」这类问题。
WebRTC
WebRTC(Web Real-Time Communication)出现之前,DNS 几乎是浏览器唯一使用的基于 UDP 的协议。WebRTC 提供的三大功能中,MediaStream 与网络无关,RTCPeerConnection 和 RTCDataChannel 都是基于 UDP,如图:
+———————–+————————-+
| RTCPeerConnection | RTCDataChannel |
+———————–+————————-+
| SRTP | SCTP |

  • +———+————————-+
    | | DTLS |
    +————-+———————————–+
    | ICE, STUN, TURN |
    +————————————————-+
    | UDP |
    +————————————————-+
    | IP |
    +————————————————-+
    这个图比较复杂,我们从下往上介绍:
    ICE(Interactive Connectivity Establishment)框架,作用是在端与端之间建立一条有效的通道,优先直连,其次用 STUN 协商,再不行只能用 TURN 转发:
    STUN(Session Traversal Utilities for NAT)协议,解决了三个问题:1)获得外网 IP 和端口;2)在 NAT 中建立路由条目,绑定外网端口,使得到达外网 IP 和端口的入站分组能找到应用程序,不被丢弃;3)定义了一个简单的 keep-alive 机制,保证 NAT 路由条目不会因为超时而被删除。STUN 服务器必须架设在公网上,可以自己搭建,也可以使用第三方提供的公开服务,例如 Google 的「stun:stun.l.google.com:19302」。
    TURN(Traversal Using Relays around NAT)协议,依赖外网中继设备在两端之间传递数据。简单说就是通过两端都可以访问的 TURN 服务转发消息,间接把两端连起来。
    DTLS(Datagram Transport Layer Security,数据报传输层安全),本质上就是 TLS,只是为了兼容 UDP 的数据报传输而做了一些微小的修改,可以简单把它理解为 UDP 版的 TLS。
    再往上就兵分两路,一路的目标是 RTCPeerConnection,负责音频和视频数据通信,对传输速度和实时性有很高的要求,这里又有两个新的协议出现:
    SRTP(Secure Real-time Transport Protocol,安全实时传输协议)。WebRTC 中的音频和视频等实时数据都是通过这个协议传输。它是 RTP 协议的安全版。
    SRTCP(Secure Real-Time Control Transport Protocol,安全实时控制传输协议)。它会跟踪 SRTP 的运行情况,以便调整每个流的发送速率、编码品质和其他参数。它是 RTCP 协议的安全版。
    另一路的目标是 RTCDataChannel,用来在端到端之间传输任意应用数据,SRTP 是专门为传输媒体数据为设计的,不适合传输应用数据,所以这里又需要一个新的协议:
    SCTP(Stream Control Transmission Protocol,流控制传输协议)。本身 SCTP 是一个传输层协议,直接运行在 IP 协议之上,与 TCP 和 UDP 类似。但在 WebRTC 这里,SCTP 却运行于 DTLS 之上。SCTP 很好的一点是提供了交付属性选项,使用者可以指定消息是有序还是乱序,是可靠还是部分可靠,部分可靠时还可以指定使用超时重传还是计数重传策略。
    QUIC
    Google 正在试验一种新的传输层协议:QUIC(Quick UDP Internet Connections),它的本质是基于 UDP 实现 HTTP,相当于之前的 TCP + TLS。从目前的资料来看,QUIC 可以大幅减少建立连接的时间,这是通过简化握手步骤从而减少 RTT(Round-Trip Time)来实现的,类似于 TFO(TCP Fast Open)。有兴趣的同学可以点这个连接围观,据说 Google 自家服务来自 Chrome 的请求中,已经有 50% 使用了 QUIC 协议。
    最后表达下对 Google 的佩服。Google 为了优化 WEB 性能,在浏览器(Chrome)、排版引擎(Blink)、JS 引擎(V8)、图片格式(WebP)、传输层协议(TCP 的 TFO,QUIC)、应用层协议(SPDY)以及 HTML5(从 Google Gears 开始)等等方面都做了大量努力,实在是技术型公司典范,叹为观止!

https://imququ.com/post/network-protocol-in-browser.html

捧个钱场?