本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等
网络
首先熟悉一下, 什么是网络,网络是几乎可以实时相互发送和接收数据的计算机和其他设备的集合。网络通常用线缆连接,数据为转换为电磁波,通过线缆移动。不过,无线网络会通过无线电波传输数据,许多长距离的传输现在会用通过玻璃纤维发送可见光的光纤电缆来完成。
网络中的每台机器为一个节点(node)。大多数节点是计算机,但是打印机、路由器、网桥、网关、ATM机也都是节点。每个网络节点都有地址 (address),这是用于唯一标识节点的一个字节序列。每个地址中的字节越多,可用的地址就越多,就可以有更多的设备同时连入网络。
不同的网络会以不同的方式分配地址。以太网(Ethernet)地址与物理以太网硬件关联。以太网硬件的生产厂家使用预分配的厂商编码确保他们的硬件地址或与其他厂家的硬件地址不冲突。每家厂商都要负责保证不会生产出两块地址相同的以太网卡。
所有现代计算机网络都是包交换(分组交换)网络:流经网络的数据分割成小块,称为包(packet,也称分组),每个包都单独加以处理。每个包都包含了由谁发送和将发往何处的信息。
计算机来回传递数据时还有另一个重要的一个点,那就是协议,协议(protocol)是定义计算机如何通信的一组明确的规则:包括地址格式、数据如何分包等。针对网络通信的不同方面,定义有很多不同的协议。例如:Hypertext Transfer Protocol(HTTP)。
网络分层
通过网络发送数据是一项复杂的操作,必须仔细地协调网络的物理特性以及所发送数据的路基特征。为了对应用程序开发人员和最终用户隐藏这种复杂性,网络通信的不同方面被分解为多个层。每一层表示为物理硬件(即线缆和电流)与所传输信息之间的不同抽象层次。在理论上,每一层只与紧挨其上和其下的层对话。将网络分层,这样就可以修改甚至替换某一层的软件,只要层与层之间的接口保持不变,就不会影响到其他层。
上面的图显示了网络中可能存在的协议栈。
有几种不同的分层模型,分别适合特定类型网络的需要。我这边主要介绍适用于Internet的标准TCP/IP四层模型,如下图所示:
主机网络层
主机网络层定义了一个特定的网络接口(如以太网或WiFi天线)如何通过物理连接向本地网络或世界其他地方发送IP数据报。主机网络层中,由连接不同计算机的硬件(线缆、光纤电缆、无线电波或烟信号)组成的部分有时称为网络的物理层。Java程序员不需要担心这一层,除非出现了问题,比如插头从计算机后面掉了下来,或者有人挖断了你与外部世界之间的T-1线。换句话说,Java从来都看不到物理层。
网际层
网际层主机网络层的下一层,这也是作为Java程序员需要考虑的第一层,网际层协议定义了数据位和字节如何组织为更大的分组,称为包,还定义了寻址机制,不同计算机要按这个寻址机制查找对方。网际协议(IP)是世界上使用最广泛的网际层协议,也是Java唯一理解的网际层协议。
网际协议主要是两个协议:IPV4和IPV6,IPV4使用32位地址,IPV6使用128位地址,另外还增加了一些技术特性来帮助完成路由。这是两个完全不同的网络协议,如果没有特殊的网关/或隧道协议,即使在相同的网络上它们也无法做到互操作,不过Java几乎对你隐藏了所有这些区别。
除了路由和寻址,网际层的第二个作用是支持不同类型的主机网络层相互对话。Internet路由器会完成WiFi和Ethernet、Ethernet和DSL、DSL和光纤往返等协议之间的转换。如果没有网际层或类似的分层,则每个计算机只能与同一类网络上的其他计算机对话。网际层负责使用同够协议将异构网络相互连接。
传输层
原始数据报有一些缺点。最显著的缺点是不能保证可靠传送,即使能传送也可能在传输中遭到破坏。首部校验只能检测首部中的破坏情况,而不能检测数据报中的数据部分。最后即使数据报能到底目的地而未被破坏,也不一定会以发送时的顺序到达。
传输层(transport layer)负责确保各包以发送的顺序接收,并保证没有数据丢失或破坏。如果丢包,传输层会请求发送方重传这个包。为实现这个目标,IP网络会给每个数据报添加一个附加首部,其中包含有更多信息。
这一层上主要有两个协议。第一个是传输控制协议(Transmission Control Protocol,TCP),这是一个开销很高的协议,支持对丢失或破坏的数据进行重传,并按照发送时的顺序进行传送。第二个协议是用户数据报协议(User Datagram Protocol ,UDP),它允许接收方检测被破坏的包,但不保证这些包以正确的顺序传送(或者包有可能根本未传送)。但是,UDP通常比TCP快。TCP称为可靠(reliable)协议;UDP是不可靠(unreliable)协议。
应用层
向用户传送数据的层称为应用层(application layer)。它下面的三层共同定义了数据如何从一台计算机传输到另一台计算机。应用层确定了数据传输后的操作。有用户Web的HTTP,还有用户电子邮件的SMTP、POP、IMAP、;用于文件传输的FTP、FSP、TFTP,用于文件访问的NFS;用于文件共享的Gnutella和BitTorrent;用于语音通信的会话启动协议(Session Initiation Protocol,SIP)和Skype等。此外你的程序可以在必要时定义自己的应用层协议。
IP、TCP、UDP
IP设计为允许任意两点之间有多个路由,可以绕过被破坏的路由器实现数据包的路由。由于两点间存在多个路由,并且两点间的最短路径可能由于网络业务流量或其他因素而随时间改变,所以构成某个特定数据流的包可能不会采用相同的路由。另外,即使它们全部到达,也可能不会以发送的顺序到达。为了改进这种基本机制,将TCP置于IP之上,使连接的两端能够确认接收IP包,以及请求重传丢失或被破坏的包。此外,TCP允许接收端的包按发送时的顺序重新组合在一起。
不过,TCP会有很大的开销。因此,如果有些情况丢失个别包不会完全破坏数据的话,也可以使用UDP发送数据包,而不需要TCP提供保证。UDP是不可靠协议,它不能保证包一定会到达目的地,也不保证包会以发送时的相同顺序到达。但是它开销小,速度快,也可以在应用层的UDP数据流中建立纠错码,来解决数据丢失问题。
可以在IP之上运行很多其他协议。但是Java支持的协议只有TCP和UDP,以及建立在TCP和UDP之上的应用层协议。所有其他传输层、网际层和更底层的协议,如ICMP、IGMP、ARP、RARP、RSVP和其他洗衣在Java程序中都只能通过连接到原生代码来实现。
IP地址和域名
IPv4网络中的每台计算机都有一个4字节的数字标识。一般写为点分四段格式,如192.1.32.90,这4个数中,每个数都是一个无符号字节,范围从0到255。IPv4网络中的每台计算机都有一个唯一的4节地址。当数据通过网络传输时,包的首部会包括要发往的机器地址(目的地址)和发送这个包的机器地址(源地址)。沿路的路由器通过检查目的地址来选择发送数据包的最佳路由。包括源地址是为了让接收方知道要向谁回复。
虽然计算机可以轻松地处理数字,但人类对于记忆数字却不在行。因此开发了域名系统(Domain Name System,DNS)用来将人类易于记忆的主机名(如www.12345.com
)转换为数字Internet地址(如208.201.243.99)。当Java程序访问网络时,他们需要同时处理数字地址和相应的主机名。这些方法由java.net.InetAddress类提供。
端口
如果每台计算机一次只做一件事情,那么地址可能就足够了。但是,现代计算机同时要做很多不同的事情。电子邮件需要与FTP请求分开,而FTP又要与Web业务流分开。这是通过端口(port)实现的。每台有IP地址的计算机都有几千个逻辑端口(确切地讲,每个传输层协议有65535个端口)。这些只是计算机内存中的抽象,不表示任何物理实物,与USB端口不同。每个端口由1到65535之间的一个数字标识。每个端口可以分配给一个特定的服务。
防火墙
Internet上有些顽皮的人。为了把他们关在门外,在本地网络建立一个访问点,检查所有进出该访问点的业务流通常很有用。位于Internet和本地网络之间的一些硬件和软件会检查所有进出的数据,以保证其合法性,这就称为防火墙(firewall)。防火墙通常是将本地网络连接到更大的Internet的路由器的一部分,还可以完成其他任务,如网络地址转换。此外,防火墙也可以是单独的机器。防火墙主要还是负责检查传入或传出其网络接口的各个包,根据一组规则接收或拒绝这些包。
过滤通常是基于网络地址和端口的。Java与防火墙没有太大关系,除非防火墙总是碍你事。