计算机网络笔记(第二章)

第二章 应用层

在这一章中我们将会学习有关网络应用的原理和实现方面的知识,OSI五层结构中,我们采用自顶向下的方法,先从应用层开始学习。应用层概念包括应用程序所需要的网络服务、客户和服务器、进程和运输层接口等。

应用层协议原理

网络核心设备并不在应用层上起作用,而仅在较低层起作用,特别是在网络层及下面层次起作用。

网络应用程序体系结构

应用程序体系结构(application architecture)由应用程序研发者设计,规定了如何在个各种端系统上组织该应用程序。两种主流体系结构之一:客户 - 服务器体系结构或对等(P2P)体系结构。

客户-服务器体系结构(client-server architecture):有一个总是打开的主机称为服务器,它服务于来自许多其他称为客户的主机的请求。

利用客户-服务器体系结构,客户相互之间不直接通信,服务器具有固定的、周知的地址,并且因为该服务器总是打开,客户总是能够通过向该服务器的IP地址发送分组来与其联系。

配备大量主机的数据中心(data center)常被用于创建强大的虚拟服务器。

P2P体系结构(P2P architecture):应用程序在间断连接的主机对之间使用直接通信,这些主机对被称为对等房。该体系结构被称为对等方到对等方的。包括文件共享、对等方协助下载加速器(迅雷)、因特网电话等。

某些应用具有混合的体系结构,结合了客户-服务器和P2P的元素。

P2P体系结构的特性之一:自扩展性(self-scalability)

进程通信

进行通信的实际上是进程(process),而不是程序。当多个进程运行在相同的端系统上时,它们使用进程间通信机制相互通信。

在两个不同端系统上的进程,通过跨越计算机网络交换报文(message)而相互通信。

客户和服务器进程

对每对通信进程,我们通常将这两个进程之一标识为客户(client),而另一个进程标识为服务器(server)。对于Web而言,浏览器是一个客户进程,Web服务器是一台服务器进程。

在P2P文件共享的某些应用中,一个进程能够既是客户又是服务器。

在一对进程之间的通信会话场景中,发起通信(即在该会话开始时发起于其他进程的联系)的进程被标识为客户,在会话开始时等待联系的进程时服务器

进程与计算机网络之间的接口

进程通过一个称为套接字(socket)的软件接口向网络发送报文和从网络接受报文。套接字是同一台主机内应用层与运输层的接口。由于该套接字是建立网络应用程序的可编程接口,因此套接字也称为应用程序和网络之间的应用程序编程接口(Spplication Programming Interface, API)

应用程序开发者可以控制套接字在应用层端的一切,但是对该套接字的运输层端几乎没有控制权。应用程序开发者对于运输层的控制仅限于:1.选择运输层协议;2.也许能设定几个运输层参数,如最大缓存和最大报文段长度(如果可供选择的话),则应用程序就建立在由该协议提供的运输层服务之上。

进程寻址

在一台主机上运行的进程为了向在另一台主机上运行的进程发送分组,接受进程需要有一个地址。为了标识该接受进程,需要两种信息:1.主机的地址;2.在目的主机中制定接受进程的标识符。

在因特网中,主机由器IP地址(IP address)标识,接受进程由目的地端口号(port number)标识,例如,Web服务器用端口号80标识,邮件服务器进程(使用SMTP协议)用端口号25来表示。

可供应用程序使用的运输服务

当开发一个应用时,必须选择一种可用的运输层协议,运输层能为应用程序提供什么样的服务?我们大体能够从四个方面对应用程序服务要求分类:可靠数据传输、吞吐量、定时和安全性。

可靠数据传输

由应用程序的一端发送的数据正确、完全地交付给该应用程序的另一端,如果一个协议能够提供这样的确保数据交付服务,就认为提供了可靠数据传输(reliable data transfer)

当一个运输层协议不提供可靠数据传输时,由发送进程发送的某些数据可能到达不了接受进程。这可能能被容忍丢失的应用(loss-tolerant application)所接受,如多媒体应用。

吞吐量

在沿着一条网络路径上的两个进程之间的通信会话场景中,可用吞吐量就是发送进程能够向接受进程交付比特的速率。

具有吞吐量要求的应用程序被称为带宽敏感的应用(bandwidth-sensitive application)

带宽敏感的应用具有特定的吞吐量的要求,而弹性应用(elastic application)能够根据当时可用的带宽或多或少地利用可供使用的吞吐量。电子邮件、文件传输以及Web传送都属于弹性应用。

定时

运输层协议也能提供定时保证。

安全性

运输层协议能够为应用程序提供一种或多种安全性服务。除了机密性以外,还包括数据完整性和端点鉴别等。

因特网提供的运输服务

TCP服务

TCP服务模型包括面向连接服务和可靠数据传输服务。

面向连接的服务:TCP让客户和服务器交换运输层控制信息。这个所谓握手过程提醒客户和服务器为大量分组到来做好准备,握手后,一个TCP连接在两个进程的套接字之间建立。全双工,即连接双方的进程可以在此连接上同时进行报文转发。当应用程序结束报文发送时,必须拆除该连接。

可靠的数据传送服务:无差错、按适当顺序交付所有发送的数据。没有字节的丢失和冗余。

UDP服务

UDP是一种不提供不必要服务的轻量级运输协议,它仅提供最小服务。UDP无连接,没有握手过程。UDP协议提供一种不可靠数据传送服务,没有拥塞控制等。

因特网运输协议所不提供的服务

目前因特网运输层协议并没有提供吞吐量和定时保证

应用 应用层协议 支撑的运输协议
电子邮件 SMTP TCP
远程终端访问 Telnet TCP
Web HTTP TCP
文件传输 FTP TCP
流式多媒体 HTTP TCP
因特网电话 SIP、RTP、专用 UDP或TCP

应用层协议

应用层协议(application-layer protocol)定义了运行在不同端系统上的应用程序进程如何相互传递报文。特别是应用层协议定义了:

1.交换的报文类型,例如请求报文和响应报文。

2.各种报文类型的语法,如报文中的各个字段及这些字段是如何描述的。

3.字段的语义,即这些字段中的信息的含义。

4.确定一个进程何时以及如何发送报文,对报文进行响应的规则。

Web和HTTP

HTTP概况

Web的应用层协议是超文本传输协议(HyperText Transfer Protocol, HTTP),HTTP由一个客户程序和一个服务器程序实现。

Web页面(Web page)是由对象组成的。一个对象(object)知识一个文件。多数Web页面含有一个HTML基本文件(base HTML file)以及几个引用对象。Web浏览器(Web browser)实现了HTTP的客户端,Web服务器(Web server)实现了HTTP的服务器端。

HTTP使用TCP作为它的支撑运输协议

因为HTTP服务器并不保存关于客户的任何信息,所以我们说HTTP是一个无状态协议(stateless protocol)

非持续连接和持续连接

在许多因特网应用程序中,客户和服务器在一个相当长的时间范围内通信,其中客户发出一系列请求并且服务器对每个请求进行响应。

非持续性连接:客户-服务器的交互经TCP进行,每个请求/响应对是经一个单独的TCP连接发送。

持续性连接:客户-服务器的交互经TCP进行,所有的请求及其响应经相同的TCP连接发送。

HTTP既能够使用非持续性连接,也能够使用持续性连接。默认使用持续。

两种连接的过程在《计算机网络 自顶向下方法》P66-67 举例说明

其中我们需要注意几个概念:

非持续性连接中:

1.每个TCP连接只传输一个请求报文和一个响应报文。

2.往返时间(Round-Trip Time, RTT)定义:指一个短分组从客户到服务器然后再返回客户所花费的时间。RTT包括分组传播时延、分组在中间路由器和交换机上的排队时延以及分组处理时延。

3.总的响应时间就是两个RTT加上服务器传输HTML文件的时间。

持续性连接中:

1.必须为每一个请求的对象建立和维护一个全新的连接。

2.每一个对象经受两倍RTT的交付时延,即一个RTT用于创建TCP,另一个RTT用于请求和接受一个对象。

HTTP报文格式

HTTP请求报文

一个经典的HTTP请求报文:

GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language:fr

HTTP请求报文的第一行叫做请求行(request line),其后继的行叫做首部行(header line)。请求行有3个字段:方法字段、URL字段和HTTP版本字段。方法字段可以取几种不同的值,包括GET、POST、HEAD、PUT和DELETE。URL字段带有请求对象的标识。

首部行中,Host指明了对象所在的主机。Connection:close首部行告诉服务器不使用持续连接,要求服务器发送完被请求的对象后就关闭这条连接。User-agent首部行用来指明用户代理,即想服务器发送请求的浏览器类型。Accept-language首部行表示用户想得到该对象的语言版本,如果没有指定的版本,则发送默认版本

首部行后有一个附加的回车和换行,在这之后还有一个实体体(entity body)。使用GET方法时实体体为空,使用POST方法时使用该实体体。

实体体的作用为提交表单、输入数据,POST和GET方法皆可做到。

HTTP响应报文

HTTP/1.1 200 OK
Connection: close
Date: Tue, 18 Aug 2015 15:44:04 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT
Content-Length: 6821
Content-Type: text/html
(data...............)

响应报文分为三部分:一个初始状态行(status line),六个首部行(header line),然后是实体体(entity body)。实体体是主要部分,包含了所求对象的本身。

状态行有3个字段:协议版本字段、状态码和相应状态信息。

Connection:close首部行告诉客户,发送完报文后将关闭该TCP连接。Date首部行指示服务器产生并发送该相应报文的日期和时间,这个时间不是指对象创建或者最后修改的时间,而是服务器从它的文件系统中检索到该对象,将该对象插入响应报文,并发送该响应报文的时间Server首部行指示该报文是由一台Apache Web服务器产生,类似于请求报文中的User-agentLast-Modified首部行指示了该对象创建或者最后修改的日期。Content-Length首部行指示了实体体中的对象是HTML文本。

常见的状态码和相关的对于包括:

200 OK:请求成功,信息在返回的响应报文中。

301 Moved Permanently:请求的对象已经被永久转移了,新的URL定义在响应报文的Location首部行中。客户软件将自动获取新的URL。

400 Bad Request:一个通用差错代码,指示该请求不能被服务器理解。

404 Not Found:被请求的文档不再服务器上。

505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP协议版本。

用户与服务器的交互:cookie

HTTP使用cookie对用户进行跟踪,识别用户并保存与之有关的信息。

cookie有四个组件:1.在HTTP响应报文中的一个cookie首部行;2.在HTTP请求报文中用的一个cookie首部行;3.在用户端系统中保留有一个cookie文件,并由用户的浏览器进行管理;4.位于Web站点的一个后端数据库。

响应报文中设置cookie的首部行:Set-cookie:1678

请求报文中的cookie首部行:Cookie: 1678

这部分可看《计算机网络 自顶向下方法》P70-71页

Web缓存

Web缓存器(Web cache)也叫代理服务器(proxy server),是能够代表初始Web服务器来满足HTTP请求的网络实体。Web缓存器在存储空间中保存最近请求过的对象的副本。

可以配置用户浏览器,使得用户的所有HTTP请求首先指向Web缓存器。

这一节在《计算机网络 自顶向下方法》P72页用例子进行接受

需要注意的是,Web缓存器既是服务器又是客户。当它接收浏览器请求并发回响应时,它是一个服务器。当它向初始服务器发出请求并接收响应时,它是一个客户。

Web缓存器可以大大减少对客户请求的响应时间,特别是当客户与初始服务器之间的瓶颈带宽远低于客户与Web缓存器之间的瓶颈带宽时。其次,Web缓存器能够大大减少一个机构的接入链路到因特网的通信量,降低了费用,改善了性能。

条件GET方法

HTTP协议有一种机制,允许缓存器证实它的对象是最新的。这种机制就是条件GET(conditional GET)方法。如果:1.请求报文使用GET方法;2.请求报文中包含一个If-Modified-Since首部行。那么这个HTTP请求报文就是一个条件GET请求报文。

《计算机网络 自顶向下方法》P74

因特网中的电子邮件

电子邮件是一种异步通信媒介,快速且易于分发。

因特网电子邮件系统有3个主要组成部分:用户代理(user agent)邮件服务器(mail server)简单邮件传输协议(Simple Mail Transfer Protocol, SMTP)

邮件服务器形成了电子邮件体系结构的核心。每个接收方在其中的某个邮件服务器上有一个邮箱(mailbos)

一个典型的邮件发送过程是:从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接收方的邮件服务器,然后再这里被分发到接收方的邮箱中。如果邮件不能交付,邮件服务器在一个报文队列(message queue)中保持该报文并在以后尝试再次以电子邮件的形式通知发送方。

SMTP是因特网电子邮件中主要的应用层协议。使用TCP可靠数据传输服务。SMTP有两个部分:运行在发送方邮件服务器的客户端和运行在接收方邮件服务器的服务器端。每台邮件服务器上既运行SMTP的客户端也运行SMTP的服务器端。

SMTP

SMTP是因特网电子邮件的核心,用于从发送方的邮件服务器发送报文到接收方的邮件服务器。

SMTP限制所有报文的体部分只能采用简单的7比特ASCII表示。

《计算机网络 自顶向下方法》P77页例子介绍了SMTP工作流程

SMTP一般不使用中间邮件服务器发送邮件

具体交互流程请看书P78,非常详细

邮件访问协议

邮件访问使用了一种客户-服务器体系结构,即典型的用户通过在用户端系统上运行的客户程序来阅读电子邮件。

SMTP协议是一个推协议,通过引入一个特殊的邮件访问协议来从用户代理访问邮件服务器上的邮件,目前流行的邮件访问协议:第三版的邮局协议(Post Office Protocol-Version 3, POP3)因特网邮件访问协议(Internet Mail Access Protocol, IMAP)以及HTTP。

POP3、IMAP和基于Web的邮件协议

《计算机网络 自顶向下方法》P81-82 举例说明

DNS:因特网的目录服务

主机的一种标识方法是用它的主机名(hostname),也可以使用所谓IP地址(IP address)进行标识。

一个IP地址由4个字节组成,每个字节都被句点分隔开来,表示了0~255的十进制数字。

DNS提供的服务

我们需要一种能进行主机名到IP地址转换的目录服务,这就是域名系统(Domain Name System, DNS)的主要任务。

DNS是:1.一个由分层的DNS服务器(DNS server)实现的分布式数据库;2.一个使得主机能够查询分布式数据库的应用层协议。

DNS服务器通常是运行BIND(Berkeley Internet Name Domain)软件的UNIX机器。DNS协议运行在UDP之上,使用53号端口。

DNS通常是由其他应用层协议所使用的,包括HTTP、SMTP和FTP,将用户提供的主机名解析为IP地址。

DNS给使用它的因特网应用带来额外的时延,但是通常情况下想获得的IP地址就缓存在一个“附近的”DNS服务器中,这有助于减少DNS的网络流量和DNS的平均时延。

除了进行主机主机名到IP地址的转换外,DNS还提供了一些重要的服务:

主机别名

邮件服务器别名

负载分配

《计算机网络 自顶向下方法》P84-85

DNS工作机理

DNS的一种简单设计是在因特网上只使用一个DNS服务器,该服务器包含所有的映射,客户直接将所有查询直接发往单一的DNS服务器,同时该DNS服务器直接对所有的查询用户做出响应。这种集中式设计的问题包括:

1.单点故障:如果该DNS服务器崩溃,整个因特网随之瘫痪。

2.通信容量:单个DNS服务器要处理所有的DNS查询。

2.远距离的集中式数据库:单个DNS服务器不可能“邻近”所有查询客户。

3.维护:单个DNS服务器不得不为所有的因特网主机保留记录。

分布式,层次数据库

为了处理扩展性问题,DNS使用了大量的DNS服务器,它们以层次方式组织,且分布在全世界范围内。因特网上所有的主机映射分布在所有的DNS服务器上。

有3种类型的DNS服务器:根DNS服务器顶级域(Top-Level Domain, TLD)DNS服务器权威DNS服务器

根DNS服务器:400多个根名字服务器遍布全世界,由不同的组织管理。根名字服务器提供TLD服务器的IP地址。

顶级域(DNS)服务器:对于每个顶级域(如com、org、net、edu和gov)和所有国家的顶级域(如uk、fr、ca和jp),都有TLD服务器。TLD服务器提供了权威DNS服务器的IP地址。

权威DNS服务器:在因特网上具有公共可访问主机(如Web服务器和邮件服务器)的每个组织机构必须提供公共可访问的DNS记录,这些记录将这些主机的名字映射为IP地址。一个组织机构的权威DNS服务器收藏了这些DNS机构。

根、TLD和权威DNS服务器都处在该DNS服务器层次结构中。

本地DNS服务器(local DNS server)不属于DNS服务器的层次结构,但它非常重要。每个ISP都有一台本地DNS服务器(也叫默认名字服务器)。当主机与某个ISP连接时,该ISP提供一台主机的IP地址,该主机具有一台或多台其本地DNS服务器的IP地址(通常通过DHCP)。主机的本地DNS服务器通常“邻近”本主机。

当主机发出DNS请求时,该请求被法网本地DNS服务器,它起着代理的作用,并将该请求转发到DNS服务器层次结构中。

《计算机网络 自顶向下方法》P87-88 举例说明

迭代查询递归查询

DNS缓存

为了改善时延性能并减少在因特网上到处传输的DNS报文数量,DNS广泛使用了缓存技术。

原理:在一个请求链中,当某DNS服务器接收一个DNS回答时,它能将映射缓存在本地存储器中。

**由于主机和主机名与IP地址间的映射并不是永久的,DNS服务器在一段时间后(通常设置为两天)将丢弃缓存的信息。

DNS记录和报文

共同实现DNS分布式数据库的所有DNS服务器存储了资源记录(Resource Record, RR),RR提供了主机名到IP地址的映射。每个DNS回答报文包含了一条或多条资源记录。

资源记录时一个包含了下列字段的4元组:

(Name, Value, Type, TTL)

TTL时该记录的额生存时间,它决定了资源记录应当从缓存中删除的时间。

Name和Value的值取决于Type(忽略TTL字段):

1.如果Type = A,则Name是主机名,Value是该主机对应的IP地址。例如(relay1.bar.foo.com, 145,37,93.126, A)

2。如果Type = NS,则Name是个域(如foo.com),而Value是个知道如何获得该域中主机IP地址的权威DNS服务器的主机名。例如(foo.com, dns.foo.com, NS)

3.如果Type = CNAME,则Value是别名为Name的主机对应的规范主机名。例如(foo.com, relay1.bar.foo.com, CNAME)

4.如果Type = MX,则Value是个别名为Name的邮件服务器的规范主机名。例如(foo.com, mail.bar.foo.com, MX)

如果一台DNS服务器是用于某特定主机名的权威DNS服务器,那么该DNS服务器会有一条包含用于该主机名的类型A记录。如果服务器不是用于某主机名的权威服务器,那么该服务器将包含一条类型NS记录,该记录对英语包含主机名的域;它还将包括一条类型A记录。

DNS报文

《计算机网络 自顶向下方法》P90-91

P2P文件分发

在P2P文件分发中,每个对等方能够向任何其他对等方重新分发它已经收到的该文件的任何部分,从而在分发过程中协助该服务器。

到2016年为止,最为流行的P2P文件分发协议是BitTorrent

P2P体系结构的扩展性

《计算机网络 自顶向下》P93 举例说明

BitTorrent

BitTorrent是一种用于文件分发的流行P2P协议:参与一个特定文件分发的所有对等方的集合被称为一个洪流(torrent)。在一个洪流中的对等房彼此下载等长度的文件块(chunk),典型的块长度为256KB。当一个对等房首次加入一个洪流时,它没有块。随着时间的流逝,它积累了越来越多的块。当它下载块时,也为其他对等方上载了多个块。一旦某对等方获得了整个文件,它也许(自私地)离开洪流,或(大公无私地)留在洪流中并继续向其他对等房上载块。同时,任何对等方可能在任何时候仅具有块的子集就离开洪流,并在以后重新加入该洪流中。

每个洪流具有一个基础设施节点,成为追踪器(tracker)

《计算机网络 自顶向下方法》P95-97 举例说明

视频流和内容分发网

《计算机网路 自顶向下方法》P97-98 阐述了因特网视频和HTTP流、DASH的概念

内容分发网

为了应对向分布于全世界的用户分发巨量视频数据的挑战,几乎所有主要的视频流公司都利用内容分发网(Content Distribution Network, CDN)。CDN管理分布在多个地理位置上的服务器,在它的服务器中储存Web内容的副本,并且所有试图将每个用户请求定向到一个将提供最好的用户体验的CDN位置。

CDN可以是专用CDN(private CDN),即它由内容提供商自己所拥有;另一种CDN可以是第三方CDN(third-party CDN)

CDN通常采用两种不同的服务器安置原则:

深入:通过在遍及全球的接入ISP中部署服务器集群来深入到ISP的接入网中。

邀请做客:通过在少量关键位置建造大集群来邀请到ISP做客。这些CDN通常将集群放置在因特网交换点(IXP)。

CDN操作

当用户主机中的一个浏览器指令检索一个特定的视频时,CDN必须截获该请求,以便能够:1.确定此时适合用于该客户的CDN服务器集群;2.将客户的请求重定向到该集群的某台服务器。

大多数CDN利用DNS来截获和重定向请求。

集群选择策略

任何CDN部署,其核心是集群选择策略(cluster selection strategy)

一种简单的策略是指派客户到地理上最为邻近(geographically closest)的集群。

未来基于当前流量条件为客户决定最好的集群,CDN能够对其集群和客户之间的时延和丢包性能执行周期性的实时测量(real-time measurement)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352