20世纪90年代中期的万维网，20世纪末的即时信息和对等(p2p)文件共享应用。
称为客户的主机的请求。服务器的IP是固定的，周知的，客户通过向服务器的IP发送分组与其联系。这个体系结构的着名应用程序包括：WEB、FTP、Telnet和电子邮件。
P2P具有良好的自扩展性(self-scalability)，对等端的一方可以请求文件，也可以提供文件，从而增加了应用的服务能力。P2P体系结构也是成本有效的，不像客户-服务器那样依赖于强大的服务器的数据中心。
P2P面临的挑战。
1.ISP友好，大多数住宅ISP受制于非对称宽带应用，下载要比上次快的多。但是P2P的文件分发和视频流应用改变了从服务器到住宅ISP的上载流量，因而给ISP带来了巨大压力。
3.激励。未来P2P应用的成功也取决于说服用户资源向应用提供宽带、存储和计算资源。
应用程序之间的通信实际上就是进程间的通信，当进程运行在相同端系统上时，它们使用进程间的通信机制相互通信，该通信机制的规则有该端操作系统确定。
但是在两个不同端系统的进程，是通过计算机网络交换报文(message)而相互通信。
网络应用程序由成对的进程组成，这些进程通过网络相互发送报文。通常将发送资源请求的一端称为客户，提供资源的一端称为服务器。
多数的应用程序都是由通信进程对组成，从一个进程向另一个进程发送的报文必须通过底层的的网络传输。进程通过Socket向网络发送报文和接收报文。
下图是两个经过因特网通信的进程间的套接字通信。
套接字是传输层和应用层之间的接口，也是建立网络应用程序的可编程接口，套接字也称为应用程序和网络之间的应用程序编程接口。
数据包在传输的过程中可能会丢失。如：数据包使路由器中的缓存溢出，或者是数据包中的某些比特损坏后被丢弃。
如果一个协议能够做一些工作以确保由应用程序的一端发送的数据正确、完全地交付给另一端的应用程序，那么就可以称该协议提供了可靠数据传输。
吞吐量是发送进程能够向接收进程交付比特的速率。一些有特殊吞吐量要求的应用程序可以选择能够提供某种特定速率的传输层协议。具有吞吐量要求的的应用程序称为带宽敏感的应用。
运输层也能够提供定时保证。一般都是应用在交互式实时应用程序上，如因特网、虚拟环境、电话会议和多方游戏。
运输层能够为应用程序提供一种或多种安全性服务。发送过程中进行加密，接收过程中进行解密。
上述提出了运输层的特性，接下来我们探讨一下具体的运输层协议，TCP和UDP。当我们决定创建一个新的网络应用时，需要决定使用的运输层协议。下图是常见的应用程序的服务要求。
TCP服务包括面向连接服务和可靠数据传输服务。当某个应用程序使用TCP作为其运输层协议时，该应用层序就能获得来自TCP的这两种服务。
面向连接的服务：在应用层数据报文开始流动前，TCP让客户和服务器相互交换运输层控制信息。这个交换的过程也就是我们熟悉的握手阶段，握手阶段提示客户和服务器，让他们为大量的数据报文的到来而做好准备。在握手阶段之后，一个TCP链接就在两个进程间的套接字之间建立了。这条链接是全双工的，两端都能同时收发数据包。当应用程序结束时，必须断开链接。
可靠的数据服务：通信进程能够依靠TCP，无差错，适当顺序交付所有发送的数据。
TCP也具有拥塞控制机制。
udp服务是仅提供了最小服务的轻量级协议。它是无连接的，因此两个进程通信前没有握手过程。UDP协议提供的是不可靠数据传输服务，也就是说传输过程中不保证报文的顺序和是否传到。UDP也没有拥塞控制机制，UDP的发送端可以以任何的速率向网络层注入数据。
由于TCP、UDP都没有提供加密机制，所以其发送的数据报文都是明文来的，这样安全性特别差。所以人们研制了TCP的加强版---SSL.SSL能够做TCP的所有工作，而且提供进程到进程的安全性服务，包括加密、数据完整性和站点鉴别。SSL和TCP一样具有专门的套接字API。大致的工作工程如下：发送进程向SSL套接字发送明文数据，SSL进行加密传输。在接收端,SSL进行数据解密，然后将数据发送给接收进程。
下图是常用的应用所使用的运输层协议。
我们已经学习了通过把报文发送接套接字使网络进程间实现相互通信。但是如何构造报文？报文的各个字段含义是什么?进程何时发送报文？这些问题都是应用层协议的范围。应用层协议定义了：
各种报文类型的语法，如报文中的各个字段及这些字段是如何描述的。
一个进程何时以及如何发送报文，对报文进行响应的规则。
在20世纪90年代以前，互联网的主要使用者还是研究人员、学者和大学生。它们登录远程主机，在本地主机和远程主机之间传输文件，收发新闻，收发电子邮件。这时的互联网受众很小，直到一个颠覆性的应用的出现---万维网(WorldWideWeb),Web应用的出现将互联网从只是很多数据网之一的地位提升到仅有的一个数据网。它极大地改变了人们与工作环境内外交流的方式。
Web的应用层协议是HTTP(HyperTextTransferProtocol),它是Web的核心。HTTP由两个程序实现：一个客户程序和一个服务器程序。客户程序和服务器程序运行在不同的端系统中，通过交换HTTP报文进行通信。HTTP定义了这些报文的结构以及客户和服务器进行报文交换的方式。
Web页面(Webpage)（也叫文档）是有对象组成的。一个对象只是一个文件，如JPEG、html、视屏片段这样的文件，且他们可以通过URL进行寻址。多数的Web页面含有一个的HTML基本文件(baseHTMLfile)以及引用的其他对象。如果一个页面包含HTML文本和4个JPEG图片，那么这个Web页面就有5个对象。Web浏览器（IE,FF）实现了HTTP的客户端,Web服务器(Apache,IIS)实现了HTTP的服务端。
HTTP定义了Web客户想Web服务器请求Web页面的方式，以及服务器向客户传送Web页面的方式。小图大见识：
HTTP是运行在TCP之上的协议，这说明了HTTP在通信前会进行TCP链接，建立链接之后，就可以通过双方的套接字互相发送HTTP报文信息。由于TCP是可靠的传输服务，双方发送的报文一定能够达到目的地。这里可以看出分层的好处，HTTP应用协议不用担心数据的丢失，也不关注TCP从网络的数据丢失和乱序故障中恢复的细节。
HTTP是一个无状态协议(statelessprotocol),因为服务器不存储任何关于客户请求的状态信息。（）我的猜想：这应该是因为服务器可能接收来自于数以百万计的不同浏览器的请求，如果保存每一个请求的状态信息，服务器的压力太大了。）
在因特网应用程序中，客户和服务器的通信时间通常是很长的；在这个时间内如果是为每一对请求/响应创建一个单独的连接，那么这个应用程序使用非持续连接；如果是使用一个连接为所有的请求/响应对服务，那么这个程序使用持续连接。HTTP既能使用持续连接(默认)，也能使用非持续连接。
1.非持续连接：我们通过一个假设的例子，服务器向客户端发送一个Web页面，这个页面含有一个HTML文件，10个图片文件，该页面的URL是：这个例子的步骤如下。
HTTP服务器通过它的套接字接收该请求报文，从其存储器中检索出对象,在一个HTTP响应报文中封装对象，并通过其套接字向客户端发送响应报文。
HTTP服务器进程通知TCP断开该TCP连接(实际上是直到TCP确认客户端已经完整地收到响应报文为止，它才会实际中断连接)。
HTTP客户端接收响应报文，TCP连接关闭。该报文指出封装的对象是HTML文件，客户端从响应报文中提取出该文件，解析文件得到10个JPEG图片的引用。
对每个引用的JPEG文件重复前4个步骤。
从上面的步骤可以看出，对于每一个资源文件，都会创建一个TCP链接来传输。上面的例子一共创建了11个连接。
对于上面例子的耗时，我们可以做一个简单的分析.为了简化我们的分析，我们使用往返时间(Round-TripTimeRTT)的概念；往返时间指的是一个报文信息从客户端到服务器然后再返回客户端所花费的时间。
第一阶段：建立链接阶段，涉及三次握手；即客户端向服务器发送一个小TCP报文段，服务器用一个小TCP报文段做出确认响应。最后客户端向服务器返回确认。在这一个阶段，前两次握手耗时一个RTT。
第二阶段：客户端发送请求报文，服务器接收报文并解析然后响应报文。在这一个阶段，客户端的第三次握手包含在请求报文中。所以这个阶段的耗时是一个RTT再加上传输HTML文件的时间。
2.HTTP持续连接：在探讨持续连接之前，我们先看一下非持续连接的缺点。因为它需要为每一个请求对象创建一个新的TCP连接：1.对于每一个连接，在客户端和服务器都有分配TCP的缓冲区和保存TCP变量，这给服务器带来大量的负担，因为服务器可能服务于数百万的客户请求；2.每一个请求对象的耗时都需要两个RTT再加上传输对象的时间。
HTTP持续连接在服务器发送响应之后保持TCP连接的打开，该TCP连接可以服务于整个Web页面文件的资源传输，甚至是该客户端和服务器端所有资源的传输。
那么何时关闭HTTP连接呢？
一般来说，如果一条连接经过一定时间间隔(超时)仍未被使用，HTTP服务器就关闭该连接。
下图是一个典型的请求报文:
该请求报文第一行为请求行，余下的为首部行。每一行以一个回车符和换行符结束。
下图是一个通用的请求报文格式：在首部行后接一行空行下面就是主体部分，get方法为空，post方法时实体内容为post表格的内容。
Connection:close告诉客户端，发送完报文后将关闭TCP连接。
前面我们提到过HTTP是无状态的，这能够简化服务器的设计和提高性能。但是很多的商务网站需要识别用户，以此达到购物车等服务功能。为此，HTTP使用了Cookie来实现对用户的跟踪。
cookie技术的4个组件：1.HTTP响应报文中的cookie首部行；2.HTTP请求报文中的cookie首部行；3.客户端保留一个cookie文件；4.位于Web站点的一个后端数据库。
下图是cookie的活动流程：
工作流程大致如下：1.首次访问服务器时，服务器在响应报文中包含Set-cookie首部行。
cookie实现了在无状态的HTTP之上建立一个用户会话层，这能够简化一些行为；但是也会带来隐私泄露的危害。
背景：如下图，机构网络是一个高速局域网络，它的一台路由器与因特网上的一台路由器通过一条15Mbps的链路连接。源服务器与因特网相连但是位于全世界各地。假设对象的平均大小为1Mb，从机构内的浏览器对这些源服务器的平均访问速率是每秒15个请求。假设HTTP请求报文小到可以忽略，因而不会再网络中及接入链路产生什么通信量。假设因特网时延为2秒。
计算一下总的响应时间：即从浏览器请求一个对象到接收到该对象为止的时间，为局域网时延、接入时延(两台路由器之间的时延)和因特网时延之和。
局域网上的流量强度为0.15，这最多会导致数十毫秒的延迟，可以忽略不计。但是，当流量强度接近于1时，链路上的时延将会变得非常大并且无限增长。因此我们必须进行改善。
一个解决办法是为增加接入链路的速率，如从15mbps增加到100Mbps,这样流量强度为0.15，那么接入链路上的时延也可以忽略不计，那么总的响应时间为2秒，即为因特网时延。但是这种代价很高。
FTP和HTTP都是传输文件的协议，它们有许多共同点，例如都是运输在TCP协议之上的。但是也有很多不同点，比如：1.FTP是使用两条链接来传输文件的，一条控制链接，一条数据链接。当用户主机与远程主机开始一个FTP会话时，两边的FTP进程会在21端口建立一个TCP控制链接。该链接用于发送用户名和密码，还有改变远程目录的命令。当FTP的服务端从该链接接收到一个文件传输的命令后，就发起一个到客户端的TCP链接。在同一个会话中，如果还要传输另一个文件，会建立一条新的TCP链接。这说明在FTP会话中，控制链接贯穿整个会话，而数据链接则是非持续的。2.FTP在会话期间必须保存用户的状态，因为FTP需要将每个控制链接和每个用户联系起来，随着用户在远程目录上的移动，服务器必须追踪用户在远程目录上的当前位置。这大大限制了FTP同时维系的会话总数。
回答是一个3位的数字，后面跟一个可选的信息。
自从有了因特网，电子邮件就在因特网流行起来了。当因特网还在襁褓中时，电子邮件已经成为最为流行的应用程序，年复一年，它变得越来越精细，越来越强大。
以客户端主机名(crepes.fr)和服务器主机名(hamburger.edu)双方交换报文的脚本例子来观察一下具体的流程。C开头代表的是客户端发送给TCP套接字的行，S开头代表的是服务器端发给TCP套接字的行。
HELO、MAILFROM、RCPTTO...等命令都是自解释的。
邮件报文格式和HTTP报文格式差不多，首部行表明发送人、日期、接收人、主题...等一些信息。在首部行下接一行空行后就是报文体信息了。典型的报文如下：
我们可以使用这三个协议来从邮件服务器上获取邮件。
在人类世界中，如此多的人类如何标识每一个人的身份呢？我们会通过身份证号来识别一个人。在互联网世界，那么多的主机，如何确定每一台主机呢？使用数字类型的IP地址可以确定每一台主机和其位置；通常人们喜欢用主机名(cnn.com、)来进行标识一台主机，而路由器难以处理由字符组成的不定长的主机名，所以也可以使用IP地址来进行标识。
我们已经看到识别主机的两种方式,通过主机名或者IP地址。人们喜欢便于记忆的的主机名标识方式，而路由器喜欢定长的、有着层次结构的IP地址。为了折衷这些不同的偏好，我们需要用到一种能执行主机名到IP地址转换的目录服务，这就是DNS(DomainNameSystem).DNS是一个：1.由分层的DNS服务器实现的分布式数据库；2.使得主机能够查询分布式数据库的应用层协议。DNS服务器通常是运行BIND(BerkeleyInternetNameDomain)的unix机器。DNS协议使用53号端口运行在UDP之上。
浏览器上URL中抽取出主机名，并将主机名传给DNS应用的客户端。
主机别名(hostaliasing):有着复杂主机名的主机能够拥有一个或多个别名，别名是为了方便记忆。如relay1.west-coast.enterprise.com主机名(规范主机名)，可能拥有enterprise.com别名。应用程序可以通过调用DNS来获得主机别名的规范主机名或者是IP地址。
负载分配(loaddistribution):DNS也用在冗余的服务器之间进行负载分配。例如繁忙的站点(如cnn.com)被冗余分布在多台服务器上，每台服务器有不同的ip地址。这些IP地址集合与相同的规范主机名相联系.DNS数据库中存放着这些信息。当DNS发送一个某个IP地址集合对应的规范主机名时，服务器以整个IP地址集合作为响应，但在每个回答中循环这些地址次序。因为客户端请求总是向IP地址排在前面的服务器发送HTTP请求报文，所以DNS就在所有的冗余Web服务器之间循环分配了负载。负载分配也可以用于邮件服务器。
在一个需要将主机名转换为IP地址的程序中，程序会调用DNS的客户端，并指明需要被转换的主机名(在很多基于UNIX的机器上，应用程序为了执行这种转换需要调用函数gethostbyname())。用户主机的DNS接收到后，会与DNS服务器创建一个基于53号端口的UDP连接；用户主机通过该连接发送查询报文和接收响应报文，最后响应结果会被传到调用程序那里。整个转换过程中，DNS就像是一个提供转换功能的简单的黑盒子。但是，实际上这个黑盒子非常复杂。
一种最简单的DNS设计是整个互联网上只有一个DNS服务器，但是在今天互联网爆炸的时代，很容易有以下问题出现：
通信容量(trafficvolume)。当个DNS服务器不得不处理所有的DNS查询(这个数量太大了)
远距离的集中式数据库(distancentralizeddatabase)。单个DNS服务器不可能临近每一个DNS查询，如果DNS查询与DNS服务器相距很远，中间可能要经过低速和拥塞的链路。
维护(maintenance).。单个DNS服务器将要为所有的因特网主机保留记录。这不仅使这个中央数据库非常庞大，而且它还要为每一个新添加的主机而频繁更新。
所以，单一的DNS服务器完全没有扩展能力；DNS采用的是分布式的设计分案；DNS是因特网上实现分布式数据库的精彩范例。
为了处理扩展性问题，DNS使用了大量的DNS服务器，它们以层次方式组织，并且分布在全世界范围内。没有一台DNS服务器拥有所有的主机映射。大致上分为3种DNS服务器：根DNS服务器，顶级域(TOP-LEVELDOMAIN)DNS服务器和授权(authoritative)服务器。大致上和上面的图一致。
根DNS服务器：在因特网上有13个根DNS服务器，(标号从A到M)，它们中大部分位于北美洲。
顶级DNS服务器：这些服务器负责顶级域名如com、net、edu和gov以及所有国家的顶级域名。
授权DNS服务器：在因特网上具有公共可访问的主机(如Web服务器和邮件服务器)的每个机构必须提供公共可访问的DNS记录，这些记录将主机名转换为IP地址。一个组织机构可以选择实现自己的认证DNS服务器以保存这些记录，或者是支付费用，让这些记录保存在某个服务提供商的认证服务器中。
另外还有一个本地DNS服务器，我们在网络链接中设置的DNS地址应该就是指向本地DNS服务器的。
上次的查询使用递归查询和迭代查询，从cis.poly.edu到dns.poly.edu是递归查询，因为该查询请求dns.poly.edu以自己的名义获得该映射。而后继的三个查询是迭代查询，因为所有的回答都是直接返回给dns.poly.edu(dns.poly.edu依次从根服务器和顶级服务器等查询).从理论上来讲，任何DNS查询既是递归查询又是迭代查询。
DNS缓存是为了改善延时性能并减少在因特网上到处传输的DNS报文数量而出现的，它的工作原理很简单。就是保存了上一次请求的IP/主机名映射，这个有效期一般为2天。如果本地DNS服务器中缓存了域名的映射记录，那么当访问时，可以直接在本地DNS服务器中直接返回其对应的IP地址。
共同实现了分布式数据库的所有DNS服务器存储了资源记录(ResourceRecord,RR),RR提供了主机名到IP的映射。RR的记录格式:
TTL是记录的生存时间，它决定了资源记录应当从缓存中删除的时间。
如果type=A,则name是主机名，Value是该主机名对应的IP地址。
如果type=NS,则name是一个域(如foo.com)，而Value是一个知道该如何获得该域中主机IP地址的权威DNS服务器的主机名。这个记录用于查询链来路由DNS查询。如(foo.com,dns.foo.com,NS)。
如果Type=MX,则value是一个别名为Name的邮件服务器的规范主机名。
DNS有查询报文和回答报文，两种报文的格式是一样的。
在注册域名的时候就是向DNS数据库中插入相关的域名信息，认证DNS服务器，IP地址等信息都是在注册登记机构实现注册的。
在前面我们已经学了很多的网络应用程序，也知道了网络应用程序通过调用传输层的API--socket进行编程。现在让我们来实现一个简单的网络应用程序，网络应用程序一般是客户-服务器模式的，所以我们要编写客户端程序和服务器程序。在编写网络应用前，我们要选择使用TCP还是UDP。
我们在前面已经知道，运行在不同机器上的进程通过套接字发送报文进行通信。我们通过套接字控制收发信息。
一次UDP通信大致流程如下：在报文发送出去之前，会为报文附加上目的主机的IP和其使用的Socket端口号。这样才能确定具体的接收方。发送方的源地址也是由IP和端口号组成，不过这个通常是由操作系统底层完成的，不需要手动添加。
客户端从其键盘上读取一行字符并将其发送至服务器端，
服务器接收字符串转换为大写，并将其回馈给客户端，
从大学的时候就听余老师介绍过stevens这三卷书，还听说最后一卷没写完作者就去世了，工作后也一直听人谈起，但还是没去真正读它。最近因为工作上很多涉及到网络，捉包，各种tcpdump的使用，
为什么说基于TCP的移动端IM仍然需要心跳保活？
1、前言很多人认为，TCP协议自身先天就有KeepAlive机制，为何基于它的通讯链接，仍然需要在应用层实现额外的心跳保活？本文将从移动端IM实践的角度告诉你，即使使用的是TCP协议，应用层的心
2015年11月9日，Google发布深度学习框架TensorFlow并宣布开源，并迅速得到广泛关注，在图形分类、音频处理、推荐系统和自然语言处理等场景下都被大面积推广。TensorFlow系统更新快速，官方文
第1章概述1.1引言很多不同的厂家生产各种型号的计算机，它们运行完全不同的操作系统，但TCP/IP协议族允许它们互相进行通信。这一点很让人感到吃惊，因为它的作用已远远超出了起初的设想。
开端公司组织考试，一拿到考题，就是算法里说的约瑟夫环，仔细想想以前老师将的都忘了，还是自己琢磨把～packagebasic.gzy;importjava.util.Iterator;importjava.util.LinkedList;
Linux设备分为三大类：字符设备，块设备和网络设备，这三种设备基于不同的设备框架。相较于块设备和网络设备，字符设备在kernel中是最简单的，也是唯一没有基于设备基础框架（device结构）的