Nat*_*ong 15 networking tcp http
我从事网络开发工作,但我对网络协议并不了解.我记得听到一个类比,TCP,HTTP和SSL可以被认为是围绕实际请求内容的一系列嵌套信封.
我还有一个模糊的想法TCP由数据包组成,在另一端验证.但我有点想象将HTTP请求切入数据包中......
所以基本上,我根本不理解这些东西.任何人都能对此有一个很好的概述吗?此外,是否有您推荐的适合初学者的书籍或其他资源?
Nat*_*ong 35
自从我问这个问题以来,我已经对这个话题有了更多的了解,所以我会自己解决这个问题.
描绘协议栈的最简单方法是用一系列信封包装的字母.每个信封在将信件发送给收件人时都有不同的作用,并且在旅途中根据需要添加和删除信封.
这封信本身就是一个应用层请求.例如,您在浏览器中键入"StackOverflow.com"并按Enter键.您的浏览器需要向StackOverflow服务器询问其主页.所以它写了一封信说:"亲爱的StackOverflow,请你把你的主页发给我?"
如果该信函的作者是您的浏览器,则该信函的收件人是在StackOverflow上运行的Web服务器程序.浏览器希望Web服务器以网页的形式"回写"响应.浏览器和服务器都是应用程序 - 在特定计算机上运行的程序.
因为浏览器会说HTTP,所以它用来发出请求:信中写着"GET http://stackoverflow.com ".浏览器还记下上次从StackOverflow获得的任何cookie信息("记住我?你告诉我我的登录ID是X")并添加了一些名为"header"的杂项标签信息(比如"我是Firefox"和"我可以接受HTML或文本"和"如果你用gzip压缩内容,我就可以了." 所有这些信息将有助于服务器了解如何个性化或自定义其响应.
那时,浏览器基本完成了.它把这封信交给操作系统说:"请你把它发给我?" 操作系统说,"当然." 然后它做了一些连接到StackOverflow的工作(稍后会详细介绍),然后告诉浏览器,"我正在研究它.顺便说一下,这是我为你做的一个小邮箱,称为套接字.我从StackOverflow回来,我会把它放在那里,你可以像文件一样读它." 浏览器然后愉快地等待响应.
要将请求从浏览器发送到StackOverflow,操作系统必须执行多项操作.
首先,它必须查找StackOverflow.com的地址 - 特别是IP地址.它使用DNS(我不会在这里讨论)这样做.一旦知道了IP地址,它就会知道如何将请求包装在一个称为IP层的"信封"中.
为什么我们需要IP层?好吧,曾几何时,我们没有.
你有没有看过一部老电影,有人打电话要求操作员连接它们?操作员可以将人员#1房屋的电线与人员#2房屋的电线实际连接起来.在协议栈发明之前,连接计算机很像那个电话:你需要一个点到点的专用线.
因此,例如,如果斯坦福大学的计算机科学家想要与哈佛大学的数据交换数据,那么他们需要花一大笔钱在两地之间租用专用电线("租用线路").任何进入一端的数据都在另一端可靠地传出.然而,这是非常昂贵的:想象为你想要连接的每个地方支付单独的线路!
人们意识到这不会扩大规模.我们需要一种方法来建立一个由所有用户共享的网络,例如遍布地图的巨型蜘蛛网.这样,每个用户只需要一个到网络的连接,并可以通过它与任何其他用户联系.
但那提出了一个问题.如果每个人的通信都是相同的,那么数据将如何到达正确的位置?想象一下,一堆信件倾倒在传送带上.显然,每封信都需要发给某人,否则就无法送达.
这是IP的基本思想:每台机器都需要有一个唯一标识它的IP地址.消息放在IP数据包中,类似于包含地址和返回地址的信封.
因此,一旦操作系统查找了Stackoverflow.com的IP地址,它就会将HTTP请求放入IP信封中.如果它是一个"长信",对于一个信封来说太大了,那么操作系统将它切成碎片并将其放入几个IP信封中.每个信封都说"FROM :(您的IP地址); TO :(服务器的IP地址."与HTTP请求一样,IP数据包还有其他一些杂项标题信息,我们不会在这里介绍,但基本信息想法只是"来"和"来自".
所以,在这一点上,这封信准备好了,对吗?
不完全的.这封信很容易丢失!请注意,通过IP,我们不再拥有从一个地方到另一个地方的专用线路.如果我们这样做,我们肯定会收到我们的信件:只要线路没有被打破,一切都会通过.
但是通过IP,每个人的包都被丢弃到传送带上并随身携带.皮带通向小型分拣站,称为"路由器".如果你想象像物理邮件中心这样的路由器,你可以想象一下纽约市.
"这是一封前往墨西哥城的信.我不知道该如何到达那里,但是休斯顿的车站应该能够靠近它,所以我会把它送到那里.啊,这是一封去亚特兰大的信我会把它发给夏洛特;他们应该能够向前迈进一步."
通常这个系统工作正常,但它不如拥有自己的专用线那么可靠.几乎任何事情都可能在途中发生:传送带可能会破裂或着火,其上的一切都可能丢失.或者一个人可能陷入困境一段时间,所以它的数据包交付很晚.
除此之外,因为每个人都使用这些传送带和工作站,所以没有人会特别对待他们的信件.那么如果路由器获得的字母多于它可能处理的字母,会发生什么?有一段时间,它可以将它们堆叠在一个角落(可能在RAM中),但最终,它会耗尽空间.
它的作用可能看起来令人震惊:它开始扔掉它们.
是的.而已.你可能会认为至少要回信给你,说:"对不起,我们无法递交你的来信." 但事实并非如此.如果你考虑一下,如果路由器不堪重负,可能是因为线路上的流量太多了.添加道歉笔记只会使问题变得更糟.所以它丢弃你的数据包,并不打扰告诉任何人.
显然,这是我们的HTTP请求的问题.我们需要它到达那里,我们也需要响应以便可靠地恢复.
为了确保它到达那里,我们需要某种"送货确认"服务.为此,在放入IP数据包之前,我们将围绕HTTP请求包装另一个信封.该层称为TCP.
TCP代表"传输控制协议".它的存在是为了控制本来是一个混乱,容易出错的交付过程.
如前所述,TCP允许我们为这个混乱的交付系统添加一些"交付确认".在我们将HTTP请求包装在IP数据包之前,我们首先将其放入TCP数据包.每一个都得到一个数字:数据包1的5,2的5,等等.(编号方案实际上更复杂,计算字节而不是数据包,但现在让我们忽略它.)
TCP的基本思想是:
(当事情到达另一端时获得确认比在路由器出现问题时获取错误报告要好几个原因.一个是确认通过工作连接返回,而错误会进一步阻塞非工作另一方面,我们不必相信中间路由器做正确的事情;客户端和服务器是最关心这个特定会话的人,所以他们是那些负责确保它的人作品.)
除了确保所有数据都到达另一端之外,TCP还确保接收到的数据在交付堆栈之前被重新放回正确的顺序,以防先前的数据包重新发送并稍后到达,或者中间的数据包采取了更长的路线,或其他什么.
基本上就是这样 - 通过这种传送确认使不可靠的IP网络可靠.
为什么不直接建立IP?
好吧,确认有一个缺点:它使事情变得更慢.如果遗漏了某些东西,必须重复.在某些情况下,这会浪费时间,因为您真正想要的是实时连接.例如,如果你有在IP电话交谈,或你玩实时游戏在互联网上,你想知道发生了什么,现在,即使这意味着你错过了一下发生了什么第二前.如果你停下来重复一遍,你就会与其他人失去同步.在这种情况下,您可以使用称为UDP的TCP表兄,它不会重新发送丢失的数据包.UDP代表"用户数据报协议",但很多人认为它是"不可靠的数据协议".那不是侮辱; 有时可靠性不如保持最新状态重要.
由于这两者都是有效的用例,因此IP协议在可靠性问题上保持中立是有道理的; 使用它的人可以选择是否增加可靠性.
TCP和UDP都为请求添加了另一个重要信息:端口号.
请记住,我们的原始请求来自浏览器,并且将转到Web服务器程序.但IP协议只有指定计算机的地址,而不是在其上运行的应用程序.使用StackOverflow的Web服务器的机器也可能有其他正在侦听请求的服务器程序:数据库服务器,FTP服务器等.当该机器获取请求时,它将如何知道哪个程序应该处理它?
它会知道,因为TCP请求上有一个端口号.这只是一个数字,没什么特别的,但按照惯例,某些数字被解释为某些事物.例如,使用端口号80是传统的说法"这是对Web服务器的请求".然后,服务器机器的操作系统将知道将该请求传递给Web服务器程序,而不是FTP服务器程序.
当TCP数据包开始流回您的计算机时,它们也会有一个端口号,让您的机器知道响应的程序.该数字将根据您的计算机最初创建的套接字而有所不同.
等等,什么是套接字?
还记得早些时候浏览器要求操作系统发送请求吗?操作系统表示,它将为其收到的任何回复设置一个"邮箱".该bin称为套接字.
您可以将套接字视为文件.文件是操作系统提供的接口.它说,"你可以在这里读取和写入数据,我会考虑如何将它实际存储在硬盘驱动器或USB密钥或其他任何东西上." 唯一标识文件的是路径和文件名的组合.换句话说,您只能将一个文件放在具有相同名称的同一文件夹中.
类似地,套接字是OS提供的接口.它说,"你可以在这里写请求并阅读回复." 唯一标识套接字的东西是四件事的组合:
因此,您只能在系统上拥有一个套接字,并且所有这些套接字具有相同的组合.请注意,只要它们都具有不同的源端口,您就可以轻松地将多个套接字打开到相同的目标IP和端口(例如,StackOverflow的Web服务器).操作系统将保证他们通过为每个请求选择一个任意的源端口,这就是为什么你可以让几个选项卡或几个浏览器同时请求同一个网站而不会有任何混淆; 回来的数据包都说明了你的计算机上哪个端口,这让操作系统知道"啊,这个包是用于Firefox中的tab 3"还是其他什么.
我们一直在考虑这些协议是一系列信封.在我们的示例中,该字母是一个HTTP请求,它包含在TCP中,然后包含在IP中.IP数据包将发送到正确的目标计算机.该计算机删除IP"信封"并在内部找到TCP数据包.TCP数据包有一个端口号,它允许操作系统知道哪个端口收集其信息.它回复说它得到了该数据包,并将其内容(HTTP请求)放入适当程序的正确套接字中从中读取.当该程序向套接字写入响应时,操作系统将其发送回请求者.
所以我们的"堆栈"是:
重要的是要理解这个堆栈是完全可定制的.所有这些"协议"只是标准的做事方式.如果您认为接收计算机将知道如何处理它,您可以将任何您想要的内容放入IP数据包中,如果您认为接收应用程序将知道如何处理,您可以将您想要的任何内容放入TCP或UDP数据包中它.
您甚至可以在HTTP请求中添加其他内容.您可以说其中的一些JSON数据是"电话号码交换协议",只要两端都知道如何处理它,那很好,而您刚刚添加了更高级别的协议.
当然,你可以进入堆栈的"高"是有限制的 - 也就是说,你可以在HTTP中放置一个较小的信封,在内部放一个较小的信封等,但最终你将没有任何空间去小; 你不会有任何实际内容的位.
但你可以很容易地在堆栈中"降低"; 你可以在现有的"信封"周围包裹更多的"信封".
一旦包围IP的常见"信封"是以太网.例如,当您的计算机决定向Google发送IP数据包时,它会像我们之前描述的那样将它们包装起来,但是为了发送它们,它会将它们发送到您的网卡.然后,网卡可以将IP数据包包装在以太网数据包(或令牌环数据包,如果你有一个古董设置),将它们发送到路由器并发送到那里.您的路由器删除了这些以太网"信封",检查IP地址,确定下一个最近的路由器是谁,包裹发往该路由器的另一个以太网信封,然后发送数据包.
其他协议也可以包装.也许两个设备只是无线连接,因此它们将以太网数据包封装在Wi-Fi或蓝牙或4G协议中.也许你的包需要穿过一个没有电的村庄,所以有人用带编号的页面在纸上打印包裹,骑自行车穿过城镇,然后按照页码的顺序扫描到另一台计算机.瞧!打印到OCR协议.或者,也许,我不知道,TCP over carrier pigeon会更好.
协议栈是一个美丽的发明,它运作良好,我们通常认为它是理所当然的.
这是抽象功能的一个很好的例子:每个层都有自己的工作要做,并且可以依赖其他人来处理其余部分.
(尽管这些层术语是从OSI借用的,但OSI实际上是TCP/IP的竞争标准,包括TCP/IP不使用的"会话层"和"表示层"等内容.OSI旨在成为更加理智和标准化的替代方案,但仍在讨论中,TCP/IP已经正在使用并被广泛采用.)
因为这些层可以根据需要进行混合和匹配,所以堆栈足够灵活,几乎可以容纳我们能想到的任何用途,所以它可能会存在很长时间.希望现在你可以更多地欣赏它了.