为了账号安全,请及时绑定邮箱和手机立即绑定
1. Nginx 的四层反向代理

前面我们刚开始使用 Nginx 时只是用了 http 指令块,因为是针对 http 请求进行处理。这进行的是四层反向代理,转发 TCP 或者 UDP 协议的报文。针对该层的处理,Nginx 是使用了 stream 模块进行处理,对应的是 stream 指令块,它和 http 指令块非类似,用法几乎一致。stream 指令块里面可以包含 server 指令块,server 指令块里面也可以包含 listen 指令块指定监听的端口、还可以包含 proxy_pass指令,对该端口监听的 tcp 或者 udp 报文进行转发。总之,和 http 指令块大部分用法一致。...stream { ... server { listen 3440; # 转发四层流量 proxy_pass 192.168.1.103:3440; } ...}...此外,从nginx-1.11.2版开始, ngx_stream_core_module,也同 http 模块一样支持变量,部分支持变量如下,这和 http 模块也是类似的,甚至连变量名都非常相似:$binary_remote_addr: 二进制格式的客户端地址$bytes_received: 从客户端接收到的字节数$bytes_sent: 发往客户端的字节数$hostname: 连接域名$msec: 毫秒精度的当前时间$nginx_version: nginx的版本$pid: worker进程号$protocol: 通信协议(UDP or TCP)$remote_addr: 客户端ip$remote_port: 客户端端口$server_addr: 接受连接的服务器ip,计算此变量需要一次系统调用。所以避免系统调用,在listen指令里必须指定具体的服务器地址并且使用参数bind。$server_port: 接受连接的服务器端口$session_time: 毫秒精度的会话时间(版本1.11.4开始)$status: 会话状态(版本1.11.4开始), 可以是一下几个值:200成功400不能正常解析客户端数据403禁止访问500服务器内部错误502网关错误,比如上游服务器无法连接503服务不可用,比如由于限制连接等措施导致$time_iso8601: ISO 8601时间格式$time_local: 普通日志格式的时间戳

2.3 四层负载均衡

四层负载均衡工作在OSI模型的传输层,由于在传输层,只有TCP/UDP协议,这两种协议中除了包含源IP、目标IP以外,还包含源端口号及目的端口号。四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。

1.1 监听连接

浏览器每发起一次请求都需要跟服务端建立连接,服务端要时刻监听有没有客户端连接。传输层协议有 TCP/UDP 两种,实现起来并没有强制说用哪一种,下面是官方文档对 Http 连接的说明:HTTP communication usually takes place over TCP/IP connections. The default port is TCP 80 .文档中指明了连接通常用的是 TCP, TCP 不用考虑数据包乱序,丢失这些问题,实现起来更简单,高效。在代码层我们可以用 Socket 来实现我们的 TCP 传输服务。

2. Socket 的基础概念

Socket 翻译成中文是“套接字”,它是应用层和传输层中间的一个抽象中间件,它封装了底层的 TCP / IP 协议族,并向上暴露 API 给应用层,从而向上屏蔽底层协议细节。 所以 Socket 可以作为底层网络门面来让我们不在拘泥于复杂的底层传输协议,而将更多的重心放在自己的功能开发上。 下图是 Socket 的一个整体工作原理:每个 Socket 对象都对应着一个 IP 地址和一个端口号,用来标识互联网上的唯一目的地址,然后就可以通过 TCP 或者 UDP 将数据发送给对方。

1.3 Transports

Transports 代表网络中两个通信结点之间的连接。Transports 负责描述连接的细节,比如连接是 TCP 的还是 UDP 等。它们被设计为“满足最小功能单元,同时具有最大程度的可复用性,而且从协议实现中分离出来,这让许多协议可以采用相同类型的传输。Transports 实现了 ITransports 接口,它包含如下的方法:write():以非阻塞的方式按顺序依次将数据写到物理连接上;writeSequence():将一个字符串列表写到物理连接上;loseConnection():将所有挂起的数据写入,然后关闭连接;getPeer():取得连接中对端的地址信息;getHost():取得连接中本端的地址信息;

5. 小结

本文开篇简单介绍了网络的基本概念,重点介绍了 ISO/OSI 参考模型和 TCP/IP 参考模型的结构,各层的基本功能,以及二者的对比。其实,ISO/OSI 参考模型只是一个用于教学的理想模型,并没有产品实现。而目前的网络协议栈都是采用 TCP/IP 参考模型。关于 TCP/IP 参考模型中的协议有很多,我们重点介绍了常用的几个协议,这些协议是日常工作中必不可少的,需要重点掌握。尤其是以太网数据帧节点转发原理,IP 分组的存储转发原理,可靠性 TCP 的工作原理和不可靠性 UDP 的工作原理,建议重点学习。

4. 总结

本节重点是对 Java NIO Channel 类的体系结构进行了介绍。通过 channel 类的体系结构图,我们可以看出,主要是对数据读、数据写、数组形式的多缓冲读、数组形式的多缓冲写、以及和多路复用机制 Selector的集成等功能的抽象。每一个接口都对应了相应功能的实现,将这些接口进行一个组合,就是一个具体的 I/O 功能的实现,这一具体的组合是通过具体实现类来体现的。比如 ,FileChannel 是对磁盘文件的抽象,DatagramChannel 是对 UDP Socket 的抽象,Socket Channel 是对 TCP Socket 的抽象,ServerSocketChannel 是对 TCP Server 监听逻辑的抽象。通过逐个分析每一个接口所提供的能力,我们就熟悉了完整的 Java NIO Channel 体系。

3. UDP 消息序列化与反序列化

java.io.ByteArrayInputStream 和 java.io.ByteArrayOutputStream 继承自 java.io.InputStream 和 java.io.OutputStream。可以作为流的源和流的目标类,当你需要解析复杂的协议格式的时候,可以配合 java.io.DataInputStream 和 java.io.DataOutputStream 类实现消息的序列化、反序列化。下来我们定义一个简单的消息格式,通常在音视频通信中会遇到这样的消息格式,我们这里只是一个演示版本。具体字段如下:version 表示协议版本号,这是一般协议格式都会包含的一个字段。flag,一些控制标志,主要表现在用不同的 bit 位表示不同的控制标志。sequence,对每个消息进行编号,用来检测是否有丢包发生。timestamp,每一个消息都携带一个发送时间戳,可以计算网络延迟、抖动。消息体,消息的具体内容。图示如下:+-----------------+-----------------+-----------------|-----------------+| version(8 bits) | flag(8 bits) | Sequence(16 bits) |+-----------------|-----------------+-----------------------------------+| Timestamp(32 bits) |+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++| || Message Body || |+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++对于这样一个格式,通过 java.net.DatagramPacket 类读取或者是设置的是一个 byte 数组,要想解析数组中消息各个字段的含义,需要借助 java.io.ByteArrayInputStream 和 java.io.ByteArrayOutputStream 类,以及 java.io.DataInputStream 和 java.io.DataOutputStream 类。我们设计了一个 Message 类用来表示消息结构,当然 Message 类要包含协议格式中的各个字段。除了提供各个属性的 getter/setter 方法外,还提供了 serialize 和 deserialize 方法,实现了消息的序列化、反序列化。最后,我们覆盖了 toString 方,将 Message 转换成 String 形式。代码清单如下:import java.io.*;import java.net.DatagramPacket;public class Message implements Serializable { private static final int SEND_BUFF_LEN = 512; private static ByteArrayOutputStream outArray = new ByteArrayOutputStream(SEND_BUFF_LEN); private byte version =1; private byte flag; private short sequence; private int timestamp; private byte[] body = null; private int bodyLength = 0; public byte getVersion() { return version; } public void setVersion(byte version) { this.version = version; } public byte getFlag() { return flag; } public void setFlag(byte flag) { this.flag = flag; } public short getSequence() { return sequence; } public void setSequence(short sequence) { this.sequence = sequence; } public int getTimestamp() { return timestamp; } public void setTimestamp(int timestamp) { this.timestamp = timestamp; } public byte[] getBody() { return body; } public void setBody(byte[] body) { this.body = body; } public DatagramPacket serialize() { try { outArray.reset(); DataOutputStream out = new DataOutputStream(outArray); out.writeByte(this.getVersion()); out.writeByte(this.getFlag()); out.writeShort(this.getSequence()); out.writeInt(this.getTimestamp()); out.write(this.body); // 构造发送数据包,需要传入消息内容和目标地址结构 SocketAddress byte[] outBytes = outArray.toByteArray(); DatagramPacket message = new DatagramPacket(outBytes, outBytes.length); return message; } catch (IOException e) { e.printStackTrace(); } return null; } public void deserialize(DatagramPacket inMessage) { try { DataInputStream in = new DataInputStream( new ByteArrayInputStream(inMessage.getData(), 0, inMessage.getLength())); this.version = in.readByte(); this.flag = in.readByte(); this.sequence = in.readShort(); this.timestamp = in.readInt(); this.body = new byte[512]; this.bodyLength = in.read(this.body); } catch (IOException e) { e.printStackTrace(); } } @Override public String toString() { return " version: " + this.getVersion() + " flag: " + this.getFlag() + " sequence: " + this.getSequence() + " timestamp: " + this.getSequence() + " message body: " +new String(body, 0, this.bodyLength); }}通过 DataOutputStream 和 ByteArrayOutputStream 的配合,实现 serialize 功能。通过 DataInputStream 和 ByteArrayInputStream 配合,实现 deserialize 功能。Message 序列化的用法:private static final int PORT = 9002;private static final String DST_HOST = "127.0.0.1";private static short sequence = 1;SocketAddress to = new InetSocketAddress(DST_HOST, PORT);String req = "Hello Server!";Message sMsg = new Message();sMsg.setVersion((byte)1);sMsg.setFlag((byte)21);sMsg.setSequence(sequence++);sMsg.setTimestamp((int)System.currentTimeMillis()&0xFFFFFFFF);sMsg.setBody(req.getBytes());DatagramPacket outMessage = sMsg.serialize(); outMessage.setSocketAddress(to);Message 反列化的用法:Message rMsg = new Message();rMsg.deserialize(inMessage);// inMessage 是一个 DatagramPacket 类型的实例

5. 如何学习网络编程

要想学习网络编程,需要学习计算机网络基础知识。比如,TCP/IP 协议栈工作原理,分组在路由器中的存储、转发原理,可靠协议 TCP 的工作原理,不可靠协议 UDP 的工作原理等。由于网络协议栈的发展是离不开操作系统的,所以需要学习操作系统的基础知识,比如进程、线程的基本概念。学习编程必须要动手实践,只有当你亲自上机调试一些程序,你才能体会的更深刻,掌握的更牢固。最后,你需要学会使用 tcpdump 和 Wireshark 这两个抓包工具,这俩个工具是解决很多网络相关问题的利器,可以说是开发人员工具箱里面必备工具。tcpdump 是 linux 系统自带的工具,而 Wireshark 是具有图形界面的工具,一般在 Windows 系统上使用。同时,要学会应用 ipconfig、netstat 等网络工具。本系列文章的所有示例代码路径:https://github.com/haska1025/imooc-sock-core-tech/tree/master/java_netprogramming

3. 性能对比

根据前面的进程模型对比,我们可以看出:Nginx 是轻量级、支持高并发、海量请求的 web 服务器,而 Apache 是重量级、不支持高并发的 web 服务器。Nginx 在处理静态文件方面的性能要远超于Apache,而且支持压缩、缓存等配置。 Nginx 最擅长的是静态资源访问和反向代理。其反向代理模块也同时支持 4 层协议(主要是 TCP 协议/ UDP 协议)和七层协议(HTTP 协议、WebSocket 协议、WSGI 协议等)的反向代理。同时也可以作为负载均衡服务器,也支持 4 层和 7 层的负载均衡,这些优势是 Apache 无法比拟的。但是 Apache 在处理动态请求方面有较大优势,比如 rewrite(对 url 重写)功能。如果网站使用 rewrite 频繁的情况下,建议用 Apache。此外,根据 Nginx 和 Apache 的进程模型,可以看到,Apache 一个进程对应一个连接请求,而 Nginx 的一个 worker 进程可能对应很多个连接请求,这样如果 Nginx 的一个进程死掉,会影响比较多的用户请求,所以 Apache 相比 Nginx 会更稳定一些。

4. TCP/IP 协议族

TCP/IP 协议族包含了很多协议,一些比较重要的、常用的协议展现如下:依据 TCP/IP 参考模型,我们把协议栈从上到下分为 4 层,每一层都有相应的协议。应用层HTTP(Hypertext Transfer Protocol)超文本传输协议,只要你浏览页面就会用到此协议。SMTP(Simple Mail Transfer Protocol)简单邮件传输协议,用于电子邮件传输。FTP(File Transfer Protocol)文件传输协议,用于文件的上传和下载。现在 FTP 貌似用的不多了,早期主要是在公司内部、大学等研究机构用的比较多。RTMP(Real-Time Messaging Protocol)实时消息协议,用于实时流媒体传输,主要用在音视频直播领域,属于 Adobe 公司出品。不过,从 2020 年开始,Adobe 就不再支持 RTMP 协议了。SNMP(Simple Network Management Protocol)简单网络管理协议,用于电信网络设备的管理。比如,监控设备告警,对设备进行业务配置等。主要是在思科、华为等电信网络设备上用的比较多。其实,应用层除了以上诸多知名协议外,也可以是用户自定义协议。传输层TCP(Transmission Control Protocol)传输控制协议,是面向连接的、可靠的、面向字节流的传输协议。TCP 应用非常广泛,是端到端传输的基石。UDP(User Datagram Protocol)用户数据报协议,是无连接的、不可靠的、面向消息的传输协议。UDP 实时性好,效率高,在音视频传输中有着广泛的应用。网络层IPv4 (Internet Protocol version 4)此协议主要是用于 IP 分组的路由转发,是路由器主要实现的协议。我们经常说的 IP 地址是指 IPv4 地址,用 32 bit 来表示。IPv6 (Internet Protocol version 6)此协议工作原理类似 IPv4。之所以设计 IPv6 的目的是因为上世纪 90 年代中期,因特网爆炸式的增长,32 位 IPv4 地址不够用了,为此才设计了 128 位的 IPv6 地址。ICMP(Internet Control Message Protocol)因特网控制消息协议,主要是用于显示网络错误。比如,我们用 ping 的时候,有时会显示“网络不可达”的错误。ICMPv6 (Internet Control Message Protocol Version 6)整合了 ICMP 协议,针对 IPv6 开发的协议。IGMP(Internet Group Management Protocol)因特网组管理协议,主要是用于 IP Multicast 的场景,比如观看 IP 电视节目。链路层ARP(Address Resolution Protocol)地址解析协议,主要是用于生成 IP 地址和物理地址(比如以太网 MAC 地址)的映射表,用于数据包的快速转发。RARP(Reverse Address Resolution Protocol)反向地址解析协议,主要是用于生成物理地址和 IP 地址的映射。以上这些协议属于计算机网络的基础协议,需要很好的掌握其工作原理。

1. 前言

TCP 的英文全称是 Transmission Control Protocol,翻译成中文叫做传输控制协议,它是 TCP/IP 协议族中非常重要的一个传输层协议。TCP 是一个面向连接的、面向字节流的、可靠的传输层协议,有丢包重传机制、有流控机制、有拥塞控制机制。TCP 保证数据包的顺序,并且对重复包进行过滤。相比不可靠传输协议 UDP,TCP 完全是相反的。对于可靠性要求很高的应用场景来说,选择可靠 TCP 作为传输层协议肯定是正确的。例如,著名的 HTTP 协议和 FTP 协议都是采用 TCP 进行传输。当然 TCP 为了保证传输的可靠性,引入了非常复杂的保障机制,比如:TCP 连接建立时的三次握手和连接关闭时的四次挥手机制,滑动窗口机制,发送流控机制,慢启动和拥塞避免机制等。当然,操作系统的网络协议栈已经实现了这些复杂的机制,本小节主要是介绍通过 Java 语言编写 TCP 客户端、服务器程序的方法。编写 TCP 客户端、服务器程序主要分为如下几个步骤:创建客户端 Socket,连接到某个服务器监听的端口,需要指定服务器监听的 host 和 port。host 可以是 IP 地址,也可以是域名。创建服务端 Socket,绑定到一个固定的服务端口,监听客户端的连接请求。客户端发起连接请求,完成三次握手过程。TCP 连接建立成功后,双方进行数据流交互。数据流交互完成后,关闭连接。

3. ISO/OSI 七层模型和 TCP/IP 四层模型

网络分层的主要是采取分治策略,使得复杂问题简单化,网络模块组件化。每一层都有自己的职责,每一层对上一层提供服务,这样实现了职责单一,进而提高了组件的复用性。。在网络标准化过程中,国际标准化组织(ISO)把计算机网络分为 7 层,叫做开放系统互联模型(OSI)。同时,TCP/IP 四层模型正处于开发阶段。最终,OSI 模型和 TCP/IP 模型有一些差异,对比图如下:从图中可以看出,ISO/OSI 七层模型和 TCP/IP 四层模型之间存在两个差异:TCP/IP 参四层模型没有表示层和会话层。那么,TCP/IP 参考模型不需要表示层和会话层吗?答案是:“如果需要这两层,就由应用程序员来实现”。经过这么多年发展来看,需要表示层和会话层的场景并不多。TCP/IP 模型好像没有链路层,其实在网络协议实现过程中,链路层包含了网卡驱动部分和物理介质部分,所以通常把二者统一叫做链路层。各层具体功能解释如下:应用层(Application Layer) 是由应用程序自定义的协议格式。不同的领域,对网络应用程序的需求是不同的,必须给用户自定义协议格式的权利。最广泛的应用层协议应该是 HTTP 了吧,几乎每个人都在用。表示层(Presentation)主要是定义数据格式。比如,加密和解密、压缩和解压缩。在 TCP/IP 模型中,表示层协议包含在应用层里。比如 SSL/TLS 协议。会话层(Session Layer)用于在两个通信实体之间建立会话、维护会话、终止会话。设置检查点,当系统出现崩溃拉起后,通过寻找检查点恢复运行。在 TCP/IP 模型中,会话层协议包含在应用层里。比如 NetBIOS 协议。传输层(Transport Layer) 是在两个通信主机之间进行报文传送。在 TCP/IP 模型中最重要的两个传输协议就是 TCP 和 UDP,前者是可靠的、面向字节流的传输;后者是不可靠的、面向数据报(Datagram)的传输。提示:通常把 TCP 传输的报文称作报文段(Segment)。通常把 UDP 传输的报文称作消息(Message)或者是数据报(Datagram)。网络层(Network Layer)是将 IP 分组从源端路由到目的端。网络层是为传输层服务的,在发送端的网络层收到传输层的数据后,必要时会对数据切片以后再封包发送。实现网络层协议是路由器的主要职责,是构建通信子网的基础。比如, RIP、OSPF 就是最基础的路由协议。路由器是通过 IP 分组的目的 IP 地址查找本地路由表,寻找转发的目标端。所以路由器的主要工作就是路由选择和转发,IP 分组是逐跳(hop)转发的。提示:通常把网络层传输的报文叫做 IP 分组(Packet)。链路层(Data Link Layer)是为网络层服务的。发送的时候将网络层的数据分片,封装成帧(Frame),然后顺序发送。与网络层实现端到端的路由不同,链路层是实现节点之间的数据传送。常用的链路层协议就是以太网(Ethernet)协议。提示:通常把链路层传输的报文叫做帧(Frame)。物理层(Physical Layer)是描述如何在物理介质中传输 bit 位。比如,用多少伏电压表示“1”,用多少伏电压表示“0”等。我们把分层的网络参考模型叫做协议栈(Protocol Stack)。目前所有网络协议栈的实现都采用了 TCP/IP 参考模型。协议栈的实现是包含在操作系统内核中的,比如 Windows 和 Unix-like 系统。

2. Socket 选项的概念

操作系统协议栈支持的 Socket 选项参数有很多,汇总起来如下图所示:从图中可以看出,Socket 选项按照级别进行分类,级别有很多种,但是总结起来分两类:通用 Socket 级别的选项。枚举值为 SOL_SOCKET。协议相关的选项。协议栈为我们提供了控制所有协议的选项,比如 IP、IPv6、TCP、UDP、ICMP 等。枚举值的格式为 IPPROTO_XXX,XXX 代表协议。每一种选项级别下面包含了很多选项参数。比如,通用 Socket 选项的级别枚举值是 SOL_SOCKET,其下面包含 SO_RCVBUF 和 SO_SNDBUF 选项参数;IP 协议选项的级别的枚举值是 IPPROTO_IP,其下面包含 IP_TTL、IP_TOS 等选项参数。在 Linux 系统下,所有的选项参数都可以在帮助手册里面查找,具体方法如下:通用 Socket 级别选项参数man 7 socketIP 协议级别选项参数:man 7 ipIPv6 协议级别选项参数:man 7 ipv6TCP 协议级别选项参数:man 7 tcpUDP 协议级别选项参数:man 7 udpSocket 选项参数最终是如何设置到协议栈的呢?协议栈提供了 getsockopt() 和 setsockopt() 两个 C 语言函数,分别用于获取和设置选项参数。调用两个函数所需要包含的头文件,以及他们的声明如下:#include <sys/types.h> #include <sys/socket.h>int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);如果你对系统本身的 Socket 选项感兴趣,可以通过 man 查找相关帮助。本节重点介绍通用 Socket 选项。

2. Java DatagramPacket 分析

Java 抽象了 java.net.DatagramPacket 类表示一个 UDP 数据报,主要功能如下:发送:设置发送的数据。设置接收此数据的目的主机的 IP 地址和端口号。获取发送此数据的源主机的 IP 地址和端口号。接收:设置接收数据的 byte 数组。获取发送此数据的源主机的 IP 地址和端口号。获取接收此数据的主机目的主机的 IP 地址和端口号。接收数据的构造方法:public DatagramPacket(byte[] buffer, int length)public DatagramPacket(byte[] buffer, int offset, int length)当接收数据的时候,需要构造 java.net.DatagramPacket 的实例,并且要传入接收数据的 byte 数组,然后调用 java.net.DatagramSocket 的 receive 方法就可以接收数据。当 receive 方法调用返回以后,发送此数据包的源主机 IP 地址和端口号保存在 java.net.DatagramSocket 的实例中。发送数据的构造方法:public DatagramPacket(byte[] data, int length,InetAddress destination, int port)public DatagramPacket(byte[] data, int offset, int length,InetAddress destination, int port)public DatagramPacket(byte[] data, int length,SocketAddress destination)public DatagramPacket(byte[] data, int offset, int length,SocketAddress destination)当发送数据的时候,同样需要构造 java.net.DatagramPacket 的实例,并且要传入将要发送的数据的 byte 数组,同时要传入接收此数据包的目标主机 IP 地址和端口号,然后调用 java.net.DatagramSocket 的 send 方法就可以发送数据。目标主机的 IP 地址和端口号保存在 java.net.DatagramSocket 的实例中,你可以调用它的 getSocketAddress 方法获取。获取或设置数据:public byte[] getData()public void setData(byte[] data)public void setData(byte[] data, int offset, int length)获取或设置数据的长度:public int getLength()public void setLength(int length)获取设置 IP 地址和端口号public int getPort()public InetAddress getAddress() // 只能获取 IPpublic SocketAddress getSocketAddress()// 同时获取 IP 和 Portpublic void setAddress(InetAddress remote)// 只能设置 IPpublic void setPort(int port)public void setAddress(SocketAddress remote)// 设置 SocketAddress,同时设置 IP 和 Port

2.2 分层定义以及常见协议

在画出了计算机网络的分层模型之后,我们还需要向面试官解释每一层的定义以及介绍常见的协议。2.2.1 应用层应用层(Application Layer)是 5 层协议的顶层,顾名思义,应用层的作用是通过操作系统中应用进程(例如电子邮件、浏览器文件传输)提供网络交互。应用层最常被问到的是 HTTP 协议和 DNS 域名解析协议(在之后的小节我们会详细讲解相关题目),其次还有一些后端开发过程中可能会接触的协议,例如支持文件传输的 FTP 协议(例如需要从 Windows 开发机传输文件到 Linux 服务器时使用),以及支持电子邮件的 SMTP 协议(例如需要开发电子邮件读写的相关爬虫时需要开放邮箱的 SMTP 协议)。2.2.2 传输层传输层(Transport Layer)主要是为了实现端口到端口(port to port)的通信,计算机的不同进程都会被分配不同的端口,例如域名默认的 80 端口。从接收和发送信息的角度可以分为两大功能:复用:把操作系统的多个进程利用一个传输层接口发送信息;分用:把收到的信息利用传输层接口分发到操作系统的不同进程。传输层涉及到两个常见的协议,几乎是面试必考协议:传输控制协议(TCP,Transmission Control Protocol):特点是面向连接,基于报文段传输,能够保证消息可靠交付的协议;用户数据包协议(UDP,User Datagram Protocol):特点是无连接,基于用户数据报传输,不保证消息可靠交付,只尽 "最大努力交付"。2.2.3 网络层计算机之间的通信可以分为位于同一个子网络(也就是局域网,Local Area Network)和位于不同的子网络(广域网,Wide Area Network),网络层协议解决的问题就是如何判断两台计算机是否属于同一个子网络中。网络层最常涉及的协议是 IP 协议 ,就是 TCP/IP 协议族中的 IP 网络协议,可见其重要性。此外,还有和 IP 协议相关的 ARP(Address Resolution Protocol,地址解析协议),以太网的数据传输最直接依赖的是 MAC 地址,ARP 协议的作用就是将 IP 地址转换为 MAC 地址。2.2.4 数据链路层数据链路层(Data-Link Layer)位于物理层和网络层之间,对于两个不同主机之间的数据传输,可能会经过多个路由器中转,中间的这条链路就是我们关注的重点,我们把两个主机抽象为两个点,链路层协议解决的问题就是 "点对点" 的数据传输。数据链路层将网络层交付的 IP 数据包封装成帧(Frame),其中每一帧包括了数据以及必要的控制信息(比如同步信息、寻址信息、差错控制信息),这种设计方案非常类似 TCP 协议中的控制位(由此也能看出计算机网络设计的互通性)。如果通过差错控制信息校验出了错误,那么就会在本层丢弃这个帧,纠正错误是通过网络层的 TCP 协议完成。PPP 协议(Point to Point Protocol):在两个点之间传输数据包的协议,因为本层涉及的协议在面试中考察甚少,基本可以只做简单了解。2.2.5 物理层物理层(Physical Layer)是 5 层协议模型中最底层的协议,就是通过物理手段(例如网线,电缆)将计算机连接起来,提供信息传输的物理媒介,数据由 0 和 1 二进制信号构成,传输单元是比特位。因为关于物理层的研究更偏向于通信相关的原理,我们只需要了解本层的定义即可。

首页上一页12下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号