常识----计算机网络

1.OSI 7层网络模型:应用层、表示层、会话层、运输层、网络层、链路层、物理层
OSI(开放式系统互连)参考模型是一个用于描述计算机网络通信的框架。它将网络通信分为七个不同的层级,每个层级负责不同的功能。以下是每个层级的简要介绍:**物理层(Physical Layer):**这是网络通信的最底层,负责传输原始的比特流。它定义了物理上的数据传输媒介,如光纤、电缆和无线信号等。**链路层(Data Link Layer):**链路层将物理层提供的比特流划分为数据帧,并在相邻网络节点之间进行可靠的数据传输。它还负责错误检测和纠正。**网络层(Network Layer):**网络层负责在不同的网络之间进行数据路由和转发。它将数据包从源地址传输到目标地址,并选择最佳的路径。**运输层(Transport Layer):**运输层提供端到端的数据传输服务。它负责将数据分割为较小的数据段,并确保它们以正确的顺序和完整性到达目标。**会话层(Session Layer):**会话层建立、管理和终止网络会话。它提供会话协议和同步操作,以便不同终端之间的通信可以进行正确地协调。**表示层(Presentation Layer):**表示层处理数据的格式化、加密和解密。它负责将数据转换为适合传输的格式,并确保在不同系统之间的兼容性。**应用层(Application Layer):**应用层是最高级的层级,为用户提供各种应用和服务。它包括网络应用,如电子邮件、文件传输、远程登录和网页浏览等。

2.TCP/IP四层网络模型:应用层、运输层、网际层、接口层
TCP/IP四层网络模型是一种将网络通信划分为四个层级的框架,它在实际应用中更为常见。以下是每个层级的简要介绍:**应用层(Application Layer):**应用层是最高级的层级,提供各种应用和服务。它包括网络应用程序,如HTTP、FTP、SMTP和DNS等。应用层协议定义了应用程序之间的通信规则。**运输层(Transport Layer):**运输层负责数据的可靠传输和错误检测。它主要使用两个协议:传输控制协议(TCP)和用户数据报协议(UDP)。TCP提供可靠的、面向连接的通信,而UDP则提供不可靠的、无连接的通信。**网际层(Internet Layer):**网际层负责数据在不同网络之间的路由和转发。它使用了网际协议(IP),并定义了数据包如何在网络上进行寻址和传输。网际层协议使得数据能够跨越不同的网络传输。**接口层(Interface Layer):**接口层也被称为网络接口层或链路层。它负责将数据包从一台主机传输到直接相连的网络节点。接口层定义了物理媒介和链路的规范,如以太网、Wi-Fi和PPP等。TCP/IP四层模型与OSI七层模型有一定的对应关系。运输层对应于OSI模型的传输层,网际层对应于网络层,而应用层在TCP/IP模型中涵盖了OSI模型的应用层、表示层和会话层。

3.MTU,综合OSI与TCP/IP模型
MTU(Maximum Transmission Unit)是指在网络通信中,数据链路层一次能够传输的最大数据包大小。它是以字节为单位来衡量的。MTU的大小是由网络设备或协议决定的,通常在网络设备中进行配置。不同的网络设备和协议可能有不同的MTU大小限制。MTU的大小对网络通信性能有一定的影响。较大的MTU可以减少网络通信的开销,提高传输效率,但也可能导致更高的延迟和丢包率。较小的MTU可以提高网络的稳定性,但会增加通信的开销。在实际应用中,MTU的大小通常是根据网络设备和协议的要求进行配置。常见的MTU大小为1500字节,在以太网中被广泛使用。但在某些情况下,可能需要调整MTU大小以适应特定的网络环境或需求。
综合OSI与TCP/IP模型都是用来描述计算机网络中不同层次的通信协议的模型。
综合OSI模型(Open Systems Interconnection Model)是由国际标准化组织(ISO)定义的,它将计算机网络通信分为七个不同的层次:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。每一层都有不同的功能和协议,并负责在通信中起到特定的作用。
TCP/IP模型是互联网通信协议栈的基础,它是一个较为简化的模型,由四个层次组成:网络接口层、因特网层、传输层和应用层。这个模型与综合OSI模型的层次结构不完全相同,但提供了在网络中进行通信的必需协议。TCP/IP模型是互联网基础架构的基础,所有的数据包传输都是基于TCP/IP协议。

4.MAC地址,从上向下架构:应用层、运输层、网络层、链路层、物理层
MAC地址(Media Access Control Address)是用于标识网络设备的物理地址。它是由48位二进制数表示,通常以十六进制的形式显示。MAC地址是在网络接口控制器(NIC)制造过程中分配的,每个网络设备都有唯一的MAC地址。它用于在局域网中唯一标识设备,以便数据包能够正确地发送和接收。MAC地址由6个字节组成,前3个字节称为组织唯一标识符(Organizationally Unique Identifier,OUI),用于标识设备的制造商。后面的3个字节是由制造商分配的设备唯一标识符。MAC地址通常以冒号或连字符分隔,如:00:1A:2B:3C:4D:5E。它是在数据链路层(第二层)中使用的,用于在局域网中进行设备之间的通信。需要注意的是,MAC地址是在局域网范围内具有唯一性的,不同的局域网可能存在相同的MAC地址。在跨越不同网络的通信中,使用的是IP地址来标识设备。

从上向下的网络架构包括以下层级:
应用层:应用层是网络体系结构的最高层,它提供用户与网络之间的接口,负责处理用户应用程序与网络之间的通信。常见的应用层协议有HTTP、FTP、SMTP等。
运输层:运输层负责在源主机和目标主机之间提供端到端的通信。它将应用层数据分割成较小的数据块,并为这些数据块提供可靠的传输。常见的运输层协议有TCP和UDP。
网络层:网络层负责在不同的网络之间进行数据传输和路由选择。它将数据分割成数据包,并为数据包提供源和目标地址以及路由信息。常见的网络层协议有IP。
链路层:链路层负责将数据包从一个节点传输到相邻节点。它将数据包封装成帧,并为帧提供物理地址,以便在物理介质上传输。常见的链路层协议有以太网、Wi-Fi等。
物理层:物理层负责在物理介质上传输比特流。它定义了电气、光学和机械接口的规范,并处理数据的传输速率、编码和时序等问题。常见的物理层标准有Ethernet、USB、光纤等。
这种从上到下的分层架构有助于网络的模块化设计和协议的独立性,同时也提供了灵活性和可扩展性,使得不同的网络设备和协议可以互相配合工作。

5.地址解析协议
地址解析协议(Address Resolution Protocol,简称ARP)是一种用于在局域网中将IP地址映射到MAC地址的协议。它是TCP/IP协议族中的一个重要协议,用于解决网络设备之间的通信问题。在局域网中,当一个设备需要向另一个设备发送数据时,它需要知道目标设备的MAC地址。而设备通常只知道目标设备的IP地址,而不知道其MAC地址。这时候就需要使用ARP协议来进行地址解析。ARP协议的工作原理如下:当设备A要发送数据给设备B时,设备A首先检查自己的ARP缓存中是否有设备B的IP地址对应的MAC地址。如果ARP缓存中没有对应的记录,设备A就会在局域网上广播一个ARP请求(ARP Request)消息,询问该IP地址对应的MAC地址。其他设备收到ARP请求消息后,会检查自己的IP地址是否与请求中的目标IP地址匹配。如果设备B的IP地址与请求匹配,它会发送一个ARP响应(ARP Reply)消息,将自己的MAC地址发送给设备A。设备A收到ARP响应消息后,将目标设备B的MAC地址存储到自己的ARP缓存中,并使用该MAC地址发送数据给设备B。ARP协议在局域网中起到了重要的作用,它能够动态地解析IP地址和MAC地址的映射关系,使设备能够正确地进行通信。需要注意的是,ARP协议是一种广播协议,它只能在同一个局域网中进行地址解析。如果要进行跨网段的通信,就需要使用其他协议,如ARP的扩展协议Proxy ARP或者使用路由器进行转发。

6.为啥有IP地址还需要MAC地址?同理,为啥有了MAC地址还需要IP地址?
IP地址和MAC地址在网络通信中扮演着不同的角色,彼此之间有着不同的作用和功能。IP地址(Internet Protocol Address)是在网络层(第三层)使用的地址,用于在全球范围内唯一标识网络设备。它是逻辑地址,用于在互联网中进行路由和寻址。IP地址可以按照网络类别划分为A、B、C、D、E五类,每个设备都需要拥有一个唯一的IP地址,以便进行网络通信。MAC地址(Media Access Control Address)是在数据链路层(第二层)使用的地址,用于在局域网中唯一标识网络设备。它是物理地址,由设备的制造商分配。MAC地址用于在局域网中进行直接通信,它是以太网设备的唯一标识符,用于在局域网中定位和识别设备。
IP地址提供了全球范围内的唯一标识,使得设备能够在互联网中进行通信和寻址。IP地址是逻辑地址,它可以通过路由器进行跨网络的转发和路由选择。IP地址是在网络层进行寻址和路由的基础。MAC地址提供了局域网内的唯一标识,使得设备能够在局域网中直接通信。MAC地址是物理地址,它是在数据链路层进行数据帧传输的基础。MAC地址是在局域网中进行数据链路的基础。IP地址和MAC地址在网络通信中协同工作,各自发挥着不同的作用:当设备需要与其他网络设备进行通信时,它会使用目标设备的IP地址来寻址和路由数据包。当数据包到达目标设备所在的局域网时,目标设备会使用ARP协议将目标IP地址解析为对应的MAC地址,以便直接通信。简而言之,IP地址提供了全球范围的唯一标识,用于在互联网中进行寻址和路由;而MAC地址提供了局域网内的唯一标识,用于在局域网中直接通信。

7.网络层转发数据报的流程
网络层负责转发数据报(也称为IP数据包),以实现在不同网络之间的通信。下面是网络层转发数据报的基本流程:
1.发送端主机将数据报封装在IP数据包中,包括源IP地址和目标IP地址等信息。
2.发送端主机通过ARP协议获取目标IP地址对应的MAC地址,如果目标主机在同一局域网中,会直接获取目标主机的MAC地址;如果目标主机在不同网络中,发送主机会获取默认网关(路由器)的MAC地址。
3.发送端主机将数据包发送到本地网络接口(网卡)。
4.数据包通过本地网络接口发送到局域网中,根据目标IP地址和子网掩码判断目标IP地址是否在同一子网中。
5.如果目标IP地址在同一子网中,数据包直接发送到目标主机。
6.如果目标IP地址不在同一子网中,数据包发送到默认网关(路由器)。
7.路由器接收到数据包后,根据路由表中的信息,决定将数据包发送到下一跳的接口。
8.数据包经过一系列路由器的转发,最终到达目标网络。
9.目标网络中的路由器将数据包发送到目标主机。
需要注意的是,网络层转发数据报的过程是基于IP地址的路由选择。路由器根据路由表中的信息来决定数据包的下一跳路径。路由表中包含了目的网络的IP地址和对应的下一跳接口。路由器根据最长前缀匹配原则,将数据包发送到最匹配的目的网络。此外,网络层还可以进行数据包的分片和重组,以适应不同网络的最大传输单元(MTU)。

8.TCP与UDP的区别及应用场景
TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的传输层协议,它们在数据传输方面有以下区别:连接性:TCP是面向连接的协议,通过建立可靠的连接来传输数据。UDP是无连接的协议,不需要先建立连接就可以直接发送数据。可靠性:TCP提供可靠的数据传输,它使用序号、确认和重传机制来确保数据的完整性和可靠性。UDP不提供可靠性保证,它只是简单地将数据报发送出去,不关心是否到达目标。有序性:TCP保证数据的有序性,它会按照发送顺序将数据包重新排序。UDP不保证数据的有序性,数据包的顺序可能会被打乱。流量控制和拥塞控制:TCP使用滑动窗口和拥塞控制算法来控制数据的发送速率,以避免网络拥塞。UDP没有流量控制和拥塞控制机制,数据包发送的速率由应用程序决定。
基于以上区别,TCP和UDP在应用场景上有不同的选择:TCP适用于对数据传输可靠性要求较高的应用,例如文件传输、电子邮件、网页浏览等。TCP的可靠性和有序性保证了数据的准确性,但也带来了一定的延迟和开销。UDP适用于对实时性要求较高、数据传输可靠性要求较低的应用,例如音视频流媒体、在线游戏、实时通信等。UDP的无连接性和较低的开销使得数据传输更加快速,但也容易出现丢包或乱序的情况。需要根据具体的应用需求来选择使用TCP还是UDP。有些应用可能同时使用TCP和UDP,例如在线游戏中,TCP用于传输游戏状态和控制信息,而UDP用于传输实时的游戏数据。

9.TCP首部报文格式(SYN、ACK、FIN、RST必须知道)
TCP(传输控制协议)的首部报文格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| 源端口号 | 目标端口号 |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| 序列号 |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| 确认号 |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| 数据偏移 | 保留 | 控制位 | 窗口大小 |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| 校验和 | 紧急指针 |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
| 选项(可选) |
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±+
在TCP首部报文中,以下是几个重要的控制位:
SYN(同步):用于建立连接。当某个主机向另一个主机发送SYN报文段时,它表明它想要建立一个连接,并指定初始序列号。SYN标志位为1。
ACK(确认):用于确认收到的数据。当主机接收到一个带有ACK标志位的TCP报文段时,它会向发送方发送一个确认报文段,确认收到的数据。ACK标志位为1。
FIN(结束):用于关闭连接。当主机发送一个带有FIN标志位的TCP报文段时,它表明它想要关闭连接。FIN标志位为1。
RST(复位):用于重置连接。当主机接收到一个带有RST标志位的TCP报文段时,它会立即关闭连接,并且不发送任何响应。RST标志位为1。
这些控制位在TCP的连接建立、数据传输和连接关闭过程中起着重要的作用。

10.TCP滑动窗口原理
TCP滑动窗口是一种流量控制和拥塞控制机制,用于控制发送方和接收方之间的数据传输速率。滑动窗口的原理如下:
发送方窗口(Sender Window):发送方维护一个发送窗口,表示可以连续发送的数据的范围。发送方将发送窗口分割为多个数据段,每个数据段的大小由接收方的窗口大小和网络状况决定。
接收方窗口(Receiver Window):接收方维护一个接收窗口,表示可以接收的数据的范围。接收方根据自身处理能力和可用缓冲区大小来设置接收窗口的大小。
窗口滑动:发送方根据接收方的确认信息来调整发送窗口的位置。当发送方收到接收方的确认信息时,发送窗口向前滑动,允许发送更多的数据。如果发送方没有收到接收方的确认信息,发送窗口保持不变。
流量控制:接收方通过调整接收窗口的大小来控制发送方的发送速率。接收方可以根据自身处理能力和可用缓冲区的大小来调整接收窗口的大小,从而限制发送方的发送速率,避免数据的丢失或溢出。
滑动窗口机制可以实现以下功能:
流量控制:通过动态调整发送窗口和接收窗口的大小,控制数据的传输速率,避免接收方无法及时处理大量的数据。
拥塞控制:通过观察网络的拥塞状况,动态调整发送窗口的大小,避免网络拥塞,提高网络的利用率和性能。
可靠性传输:通过使用序列号和确认号,确保数据的有序性和可靠性。发送方只发送接收方已确认的数据,接收方只接收发送方发送的正确的数据。
滑动窗口机制是TCP可靠性传输和拥塞控制的基础,它可以根据网络的状况动态调整数据的传输速率,保证数据的可靠性和网络的稳定性。

11.TCP超时重传时间选择
选择TCP超时重传时间是一个复杂的问题,需要综合考虑网络延迟、丢包率和拥塞状况等因素。以下是一些常见的TCP超时重传时间选择策略:固定超时时间:使用固定的超时时间来进行重传,例如设置为100毫秒。这种策略简单直接,但可能会导致过早或过晚的重传,影响传输性能。自适应超时时间:根据网络延迟和丢包率等动态调整超时时间。一种常见的自适应算法是指数加权移动平均(Exponential Weighted Moving Average,EWMA),根据历史的往返时间来计算平均往返时间(RTT),并根据RTT的变化来调整超时时间。
Karn算法:Karn算法是一种避免计算超时时间的算法。它基于以下假设:如果一个分组在超时时间内没有收到确认,那么后续的重传也不会收到确认。因此,Karn算法在超时后立即重传,而不是等待超时时间结束。
Jacobson算法:Jacobson算法是一种基于RTT估计的超时时间选择算法。它通过计算往返时间的偏差(RTT差)来调整超时时间,以适应网络的变化。在实际应用中,通常会结合多种策略来选择超时重传时间,以适应不同的网络环境和应用需求。此外,还可以使用拥塞控制算法来动态调整发送速率,以避免网络拥塞和丢包。
需要注意的是,选择合适的超时重传时间是一个复杂的问题,需要根据具体的网络环境和应用场景进行调整和优化。

12.子网划分、子网掩码
子网划分和子网掩码是用于将一个大的网络划分为多个较小的子网络的技术。子网划分可以提高网络的性能和安全性,同时也有助于更有效地管理IP地址。子网划分是将一个IP网络划分为多个子网络,每个子网络都有自己的网络地址和主机地址范围。子网划分可以根据需求和网络规模的大小进行灵活调整,以满足不同的网络需求。子网掩码是一个32位的二进制数,用于标识IP地址中哪些位用于网络地址,哪些位用于主机地址。子网掩码中的1表示网络地址,0表示主机地址。通过与IP地址进行逻辑与运算,可以确定IP地址的网络部分和主机部分。子网掩码的长度决定了网络地址的位数,也决定了可以分配给每个子网的主机数量。例如,如果子网掩码为255.255.255.0,那么前24位用于网络地址,后8位用于主机地址,可以分配256个主机。在进行子网划分时,需要确定子网掩码的长度,以及每个子网的网络地址和主机地址范围。常用的子网掩码长度有24位(255.255.255.0)、16位(255.255.0.0)和8位(255.0.0.0)等。
子网划分和子网掩码的使用可以帮助实现以下目标:
提高网络性能:通过将大的网络划分为多个子网络,可以减少广播域的范围,减少广播和冲突,提高网络的性能和可靠性。
提高网络安全性:通过划分子网,可以实现网络的隔离和分段,增加网络的安全性。不同的子网可以使用不同的访问控制策略和安全设置。
更有效地管理IP地址:子网划分可以根据实际需求,合理分配IP地址,避免地址浪费。同时也方便管理和维护网络。

13.网络控制报文协议ICMP
网络控制报文协议(Internet Control Message Protocol, ICMP)是用于在IP网络上发送错误消息和操作消息的协议。它通常用于网络故障排除、网络性能测量和网络管理。
以下是一些关于ICMP的重要信息:
ICMP消息类型:ICMP定义了多种消息类型,包括回显请求(Echo Request)、回显回答(Echo Reply)、目的不可达(Destination Unreachable)、超时(Time Exceeded)等。
ICMP消息结构:ICMP消息由报头和数据部分组成。报头包含消息类型、代码、校验和等字段,数据部分包含相关信息。
使用场景:ICMP常用于网络故障排查,例如使用ping命令发送回显请求消息来测试主机的可达性。它还可用于网络性能测量,例如使用traceroute命令跟踪数据包在网络中的路径。
ICMP错误消息:ICMP还可用于向发送IP数据包的源主机发送错误消息。例如,当目的地不可达时,目标主机会发送一个目的不可达消息给源主机。

14.ICMP应用举例:PING、traceroute
最常见的就是 PING 和 traceroute。
PING: PING 是一个常用的网络诊断工具,它使用 ICMP 协议来测试网络连接。它发送一个 ICMP Echo 请求消息到目标主机,并等待接收 ICMP Echo 回应消息。通过计算往返时间(RTT)和丢包率,可以评估网络的延迟和可靠性。
以下是一个使用 Python 的示例代码,演示如何使用 ICMP 进行 PING:

import os
import sys
import struct
import socket
import select
import time

ICMP_ECHO_REQUEST = 8

def checksum(source_string):
    sum = 0
    countTo = (len(source_string) / 2) * 2
    count = 0
    while count < countTo:
        thisVal = ord(source_string[count + 1]) * 256 + ord(source_string[count])
        sum = sum + thisVal
        sum = sum & 0xffffffff
        count = count + 2

    if countTo < len(source_string):
        sum = sum + ord(source_string[len(source_string) - 1])
        sum = sum & 0xffffffff

    sum = (sum >> 16) + (sum & 0xffff)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 0xffff
    answer = answer >> 8 | (answer << 8 & 0xff00)
    return answer

def receive_one_ping(my_socket, ID, timeout, dest_addr):
    timeLeft = timeout
    while True:
        startedSelect = time.time()
        whatReady = select.select([my_socket], [], [], timeLeft)
        howLongInSelect = (time.time() - startedSelect)
        if whatReady[0] == []: # Timeout
            return

        timeReceived = time.time()
        recPacket, addr = my_socket.recvfrom(1024)

        # Fetch the ICMP header from the IP packet
        icmpHeader = recPacket[20:28]
        type, code, checksum, packetID, sequence = struct.unpack(
            "bbHHh", icmpHeader
        )
        if packetID == ID:
            bytesInDouble = struct.calcsize("d")
            timeSent = struct.unpack("d", recPacket[28:28 + bytesInDouble])[0]
            return timeReceived - timeSent

        timeLeft = timeLeft - howLongInSelect
        if timeLeft <= 0:
            return

def send_one_ping(my_socket, dest_addr, ID):
    dest_addr = socket.gethostbyname(dest_addr)

    # Header is type (8), code (8), checksum (16), id (16), sequence (16)
    my_checksum = 0

    # Make a dummy header with a 0 checksum
    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
    bytesInDouble = struct.calcsize("d")
    data = (192 - bytesInDouble) * "Q"
    data = struct.pack("d", time.time()) + data.encode()

    # Calculate the checksum on the data and the dummy header
    my_checksum = checksum(header + data)

    # Now that we have the right checksum, we put that in. It's just easier
    # to make up a new header than to stuff it into the dummy
    header = struct.pack(
        "bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1
    )
    packet = header + data

    my_socket.sendto(packet, (dest_addr, 1))

def do_one_ping(dest_addr, timeout):
    icmp = socket.getprotobyname("icmp")
    try:
        my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    except socket.error as e:
        if e.errno == 1:
            raise socket.error("Not superuser. Need to run as root.")
        raise

    my_ID = os.getpid() & 0xFFFF

    send_one_ping(my_socket, dest_addr, my_ID)
    delay = receive_one_ping(my_socket, my_ID, timeout, dest_addr)

    my_socket.close()
    return delay

def ping(dest_addr, timeout=2, count=4):
    for i in range(count):
        print("Ping {}...".format(dest_addr))
        try:
            delay = do_one_ping(dest_addr, timeout)
        except socket.gaierror as e:
            print("Failed. (socket error: '{}')".format(e[1]))
            break

        if delay is None:
            print("Timeout.")
        else:
            delay = delay * 1000
            print("Response in {} milliseconds.".format(int(delay)))

# 示例用法
ping("www.example.com")

traceroute: traceroute 是另一个常用的网络诊断工具,它通过发送一系列的 ICMP Echo 请求消息,跟踪数据包从源主机到目标主机的路径。它会显示每个中间路由器的 IP 地址和往返时间(RTT)。
以下是一个使用 Python 的示例代码,演示如何使用 ICMP 进行 traceroute:

import os
import sys
import struct
import socket
import time

ICMP_ECHO_REQUEST = 8
MAX_HOPS = 30
TIMEOUT = 2.0

def checksum(source_string):
    sum = 0
    countTo = (len(source_string) / 2) * 2
    count = 0
    while count < countTo:
        thisVal = ord(source_string[count + 1]) * 256 + ord(source_string[count])
        sum = sum + thisVal
        sum = sum & 0xffffffff
        count = count + 2

    if countTo < len(source_string):
        sum = sum + ord(source_string[len(source_string) - 1])
        sum = sum & 0xffffffff

    sum = (sum >> 16) + (sum & 0xffff)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 0xffff
    answer = answer >> 8 | (answer << 8 & 0xff00)
    return answer

def receive_one_ping(my_socket, ID, timeout, dest_addr):
    timeLeft = timeout
    while True:
        startedSelect = time.time()
        whatReady = select.select([my_socket], [], [], timeLeft)
        howLongInSelect = (time.time() - startedSelect)
        if whatReady[0] == []: # Timeout
            return

        timeReceived = time.time()
        recPacket, addr = my_socket.recvfrom(1024)

        # Fetch the ICMP header from the IP packet
        icmpHeader = recPacket[20:28]
        type, code, checksum, packetID, sequence = struct.unpack(
            "bbHHh", icmpHeader
        )
        if packetID == ID:
            bytesInDouble = struct.calcsize("d")
            timeSent = struct.unpack("d", recPacket[28:28 + bytesInDouble])[0]
            return timeReceived - timeSent

        timeLeft = timeLeft - howLongInSelect
        if timeLeft <= 0:
            return

def send_one_ping(my_socket, dest_addr, ID, ttl):
    dest_addr = socket.gethostbyname(dest_addr)

    # Header is type (8), code (8), checksum (16), id (16), sequence (16)
    my_checksum = 0

    # Make a dummy header with a 0 checksum
    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
    bytesInDouble = struct.calcsize("d")
    data = (192 - bytesInDouble) * "Q"
    data = struct.pack("d", time.time()) + data.encode()

    # Calculate the checksum on the data and the dummy header
    my_checksum = checksum(header + data)

    # Now that we have the right checksum, we put that in. It's just easier
    # to make up a new header than to stuff it into the dummy
    header = struct.pack(
        "bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1
    )
    packet = header + data

    my_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
    my_socket.sendto(packet, (dest_addr, 1))

def do_one_ping(dest_addr, ttl, timeout):
    icmp = socket.getprotobyname("icmp")
    try:
        my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    except socket.error as e:
        if e.errno == 1:
            raise socket.error("Not superuser. Need to run as root.")
        raise

    my_ID = os.getpid() & 0xFFFF

    send_one_ping(my_socket, dest_addr, my_ID, ttl)
    delay = receive_one_ping(my_socket, my_ID, timeout, dest_addr)

    my_socket.close()
    return delay

def traceroute(dest_addr, max_hops=MAX_HOPS, timeout=TIMEOUT):
    dest_addr = socket.gethostbyname(dest_addr)
    print("Traceroute to {} ({}), {} hops max".format(dest_addr, dest_addr, max_hops))
    for ttl in range(1, max_hops + 1):
        print("{} ".format(ttl), end="")
        sys.stdout.flush()
        for tries in range(3):
            try:
                delay = do_one_ping(dest_addr, ttl, timeout)
            except socket.gaierror as e:
                print("Failed. (socket error: '{}')".format(e[1]))
                break

            if delay is None:
                print("* ", end="")
            else:
                delay = delay * 1000
                print("{} ms ".format(int(delay)), end="")
            sys.stdout.flush()

        print("")

# 示例用法
traceroute("www.example.com")

15.TCP流程控制
当发送方通过TCP协议向接收方发送数据时,TCP流程控制确保接收方可以正确地处理数据量。TCP流程控制主要通过滑动窗口机制来实现。
滑动窗口是一个动态的概念,它定义了发送方可以发送的字节数量。接收方通过发送窗口大小来告知发送方可以接收的字节数量。发送方根据接收方的窗口大小来控制发送速率,确保不会发送超过接收方处理能力的数据量。
当发送方发送数据后,等待接收方确认收到数据的确认应答。如果发送方收到确认应答,它会将窗口向前滑动,允许发送更多的数据。如果发送方未收到确认应答,它会减小窗口的大小,降低发送速率,以避免数据丢失或拥塞。
以下是一个示例代码,展示了如何使用Python的socket库实现TCP流程控制:

import socket

# 创建TCP连接
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 8000))

# 设置发送窗口大小
window_size = 1024

# 发送数据
send_data = b'Hello, TCP!'
send_bytes = 0

while send_bytes < len(send_data):
    # 计算当前窗口大小
    current_window_size = min(window_size, len(send_data) - send_bytes)
    
    # 发送数据
    client_socket.send(send_data[send_bytes:send_bytes + current_window_size])
    
    # 接收确认应答
    recv_data = client_socket.recv(1024)
    
    # 更新已发送字节数
    send_bytes += len(recv_data)

# 关闭连接
client_socket.close()

16. TCP拥塞控制
TCP拥塞控制是一种机制,用于在网络拥塞时控制数据流量的传输速率,以保证网络的稳定性和可靠性。拥塞控制的目标是尽可能地利用网络资源,同时避免过多的数据流量引起网络拥塞。
TCP拥塞控制的主要机制包括拥塞窗口、慢启动、拥塞避免和快速重传/快速恢复。
拥塞窗口是TCP连接中的一个参数,用于限制发送方发送的数据量。发送方根据网络的拥塞情况和接收方的反馈信息动态调整拥塞窗口的大小,以控制数据的传输速率。
慢启动是TCP连接建立后的初始阶段,发送方将初始拥塞窗口设置为一个较小的值,然后每经过一个往返时间(RTT),拥塞窗口的大小就会加倍,从而逐渐增加数据的发送速率。
拥塞避免是在拥塞窗口达到一定阈值后,发送方将每个往返时间只增加一个MSS(最大报文段长度)大小的拥塞窗口,以避免过快增加导致网络拥塞。
快速重传/快速恢复是当发送方接收到3个重复的确认(ACK)时,即判断出网络发生拥塞,发送方会立即重传丢失的数据,并将拥塞窗口减半,然后进入快速恢复阶段,每经过一个往返时间,拥塞窗口的大小增加一个MSS。
通过以上机制,TCP拥塞控制可以根据网络的拥塞情况动态地调整数据的传输速率,以保证网络的稳定性和可靠性。

17.路由器与交换机的区别
路由器和交换机是网络中常见的两种设备,它们在功能和工作方式上有一些区别。
功能:路由器主要用于连接不同网络之间的数据传输,它能够根据目标IP地址将数据包从一个网络转发到另一个网络。而交换机主要用于在同一网络内部的数据传输,它能够根据MAC地址将数据包从一个接口转发到另一个接口。
决策依据:路由器的决策依据是IP地址,它根据目标IP地址查找路由表来决定数据包的转发路径。而交换机的决策依据是MAC地址,它通过学习MAC地址和端口的对应关系来决定数据包的转发。
范围:路由器通常连接不同的网络,可以跨越多个子网,将数据包从一个网络传输到另一个网络。而交换机通常用于连接同一网络内的设备,它提供内部网络中设备之间的快速数据交换。
数据处理方式:路由器是通过网络层(IP层)进行数据转发,对数据包进行解封装和封装。而交换机是通过数据链路层(MAC层)进行数据转发,对数据帧进行转发。
网络层次:路由器通常工作在网络层,负责处理不同网络之间的数据传输,例如在互联网中连接不同的子网。而交换机通常工作在数据链路层,负责处理同一网络内的数据传输,例如在局域网中连接设备。
总的来说,路由器和交换机在网络中扮演不同的角色,路由器主要用于跨越不同网络的数据传输,而交换机主要用于同一网络内设备之间的快速数据交换。

18.TCP三次握手及状态变化。为啥不是两次握手?
TCP三次握手是建立TCP连接的过程,它的目的是确保客户端和服务器之间的通信能够正常进行。三次握手的步骤如下:
客户端向服务器发送一个SYN(同步)报文,其中包含一个随机的初始序列号(ISN)。
服务器接收到客户端的SYN报文后,会发送一个SYN-ACK(同步-确认)报文作为响应。该报文中包含了确认号(ACK)和一个自己的随机序列号(ISN)。
客户端接收到服务器的SYN-ACK报文后,会发送一个ACK(确认)报文作为最后的确认。该报文中包含了服务器的序列号加1作为确认号。
通过这个三次握手的过程,双方建立了可靠的连接,并且双方都知道彼此的初始序列号,可以进行后续的数据传输。
为什么不是两次握手呢?这是因为在TCP协议中,双方需要交换初始序列号(ISN)以及确认号(ACK),以确保双方都知道对方的初始序列号,并且能够进行可靠的数据传输。如果只进行两次握手,那么就无法确保双方都知道对方的初始序列号,可能导致数据传输的不可靠性。通过三次握手,可以避免这种情况的发生,确保连接的可靠性和正确性。

19.TCP四次挥手及状态变化。为啥不是三次挥手?
TCP四次挥手是关闭TCP连接的过程,它的目的是确保双方都完成了数据的传输并且愿意关闭连接。四次挥手的步骤如下:
客户端向服务器发送一个FIN(结束)报文,表示客户端不再发送数据。客户端进入FIN-WAIT-1状态。
服务器接收到客户端的FIN报文后,会发送一个ACK(确认)报文作为响应,表示收到了客户端的关闭请求。服务器进入CLOSE-WAIT状态。
服务器发送一个FIN报文给客户端,表示服务器也不再发送数据。服务器进入LAST-ACK状态。
客户端接收到服务器的FIN报文后,会发送一个ACK报文作为响应,表示收到了服务器的关闭请求。客户端进入TIME-WAIT状态。在TIME-WAIT状态持续一段时间后,客户端关闭连接,进入CLOSED状态。
为什么不是三次挥手呢?这是因为在关闭连接的过程中,双方需要确保对方已经收到了关闭请求,并且完成了数据的传输。通过四次挥手,可以确保双方都能够完成关闭连接的操作,并且避免了可能的数据丢失或不完整的情况。另外,通过最后的TIME-WAIT状态,可以确保在网络中所有的延迟数据都被接收和处理完毕,从而保证了连接的可靠性和正确性。因此,TCP采用四次挥手来关闭连接,以确保数据的完整性和可靠性。

20.TCP连接释放中TIME_WAIT状态的作用
TIME_WAIT状态是在TCP连接关闭后的一段时间内保持的状态。它的作用主要有以下几个方面:

  1. 确保最后一个ACK报文能够到达:在四次挥手的过程中,最后一个ACK报文可能会丢失,导致服务器无法收到确认,从而重新发送FIN报文。TIME_WAIT状态可以确保服务器在收到FIN报文后,能够收到客户端的确认ACK报文,以完成连接的关闭。
  2. 处理网络中滞留的延迟报文:在网络中,可能会有一些延迟的报文在连接关闭之前到达。TIME_WAIT状态可以确保这些报文能够被接收和处理,避免了数据的丢失或混乱。
  3. 防止旧连接的影响:在TIME_WAIT状态持续一段时间后,操作系统会释放该连接的资源并回收相关的端口。这样可以确保新的连接不会被旧连接的数据干扰。
    总的来说,TIME_WAIT状态的作用是确保连接的可靠关闭和数据的完整性。尽管TIME_WAIT状态会占用一定的系统资源,但它对于网络的稳定性和数据的可靠传输非常重要。通常,TIME_WAIT状态的持续时间是根据TCP协议的实现来确定的,一般为2倍的最大报文段生存时间(Maximum Segment Lifetime,MSL)。

21.SYN泛洪攻击。如何解决?
SYN泛洪攻击(SYN flood attack)是一种常见的DoS(拒绝服务)攻击方式,攻击者通过发送大量伪造的TCP连接请求(SYN包),耗尽服务器资源,导致合法用户无法建立有效的连接。
为了解决SYN泛洪攻击,可以采取以下几种防御措施:

  1. SYN Cookie:一种常用的防御机制是使用SYN Cookie。服务器在接收到SYN包时,不会立即分配资源和建立连接,而是根据客户端的SYN包计算一个Cookie,并将其发送给客户端。客户端在后续的ACK包中携带该Cookie,服务器根据Cookie验证请求的合法性。这种方式可以避免服务器资源被耗尽,同时保证合法用户的连接正常建立。
  2. 过滤非法请求:服务器可以设置防火墙或使用流量分析工具,过滤掉源IP地址异常、频繁发送大量SYN包的请求。可以根据一些规则或算法,例如限制每个IP地址的连接数、限制每秒钟的连接请求数等。
  3. 增加服务器资源:增加服务器的带宽、内存和处理能力,可以提高服务器的抗攻击能力。这样服务器可以更好地处理大量的连接请求,减少因攻击而导致的服务中断。
  4. 使用反向代理或负载均衡器:通过使用反向代理或负载均衡器,将请求分发到多台服务器上,可以分散攻击者的攻击压力,增加系统的容错能力。
  5. IDS/IPS:入侵检测系统(IDS)或入侵防御系统(IPS)可以监测和阻止SYN泛洪攻击。这些系统可以根据预定义的规则或行为模式,检测到异常的连接请求,并采取相应的防御措施。
    以上是一些常见的防御措施,但需要根据具体情况选择和实施,以提高系统的安全性和可靠性。

22.TCP粘包
TCP粘包(TCP packet sticking)是指在TCP传输过程中,发送方发送的多个小数据包被接收方合并成一个大数据包,或者发送方发送的一个大数据包被接收方拆分成多个小数据包接收。这种情况下,接收方无法准确地区分出每个数据包的边界,导致数据的解析和处理出现错误。
TCP粘包的产生原因主要有以下几个:

  1. 传输缓冲区:发送方和接收方的TCP传输缓冲区可能会对数据进行缓存和合并,从而导致多个小数据包合并成一个大数据包或者一个大数据包被拆分成多个小数据包。
  2. 延迟应答:接收方在接收到数据后,不立即发送ACK响应,而是等待一段时间后再发送,这样可能导致多个数据包在一个ACK响应中被确认。
  3. 数据大小不均衡:发送方发送的数据包大小不一致,可能会导致粘包现象。例如,发送方发送了两个小数据包,接收方可能会将它们合并成一个大数据包。
    为了解决TCP粘包问题,可以采取以下几种方式:
  4. 消息边界:在数据包中添加消息边界,例如在数据包的末尾添加特殊的分隔符,或者在数据包的头部添加消息长度信息。接收方根据边界信息来准确地切分数据包。
  5. 定长消息:发送方和接收方约定每个数据包的固定长度,这样接收方就可以根据固定长度来准确地切分数据包。
  6. 使用特定协议:设计特定的应用层协议,例如HTTP、WebSocket等,这些协议通常会在数据包中添加头部信息,从而可以准确地切分数据包。
  7. 使用应用层缓冲区:在接收方使用应用层缓冲区,将接收到的数据进行缓存,直到接收到完整的数据包后再进行处理。
  8. 使用专业工具:使用专门的工具或库来处理TCP粘包问题,例如Netty、Twisted等,这些工具提供了处理粘包问题的解决方案。
    需要根据具体的应用场景和需求选择合适的解决方案来解决TCP粘包问题,以确保数据的正确解析和处理。

23.TCP心跳包
TCP心跳包(TCP heartbeat)是一种用于保持TCP连接状态的机制。在TCP连接建立后,通信双方可以周期性地发送心跳包,以确保连接处于活动状态,并及时检测连接的可用性。
TCP心跳包的作用主要有以下几个:

  1. 检测连接状态:通过发送心跳包,可以检测TCP连接是否仍然处于活动状态。如果一方长时间没有收到对方的心跳包,则可以判断连接已经断开,从而及时采取相应的处理措施。
  2. 保持连接活跃:在某些情况下,TCP连接可能会因为长时间没有数据传输而被路由器或防火墙等设备关闭。通过定期发送心跳包,可以保持连接的活跃状态,避免被中间设备关闭。
  3. 优化网络性能:心跳包可以帮助检测网络延迟和丢包情况。如果发送方连续几次没有收到对方的心跳包,可能意味着网络出现了问题,可以及时采取相应的措施,例如重新建立连接或者切换到备用网络。
    实现TCP心跳包的方式有多种,常见的方式包括:
  4. 定期发送心跳包:发送方和接收方约定一个心跳包的发送间隔,例如每隔一定时间发送一个心跳包。接收方在收到心跳包后,立即发送响应,以确认连接的可用性。
  5. 交替发送心跳包:发送方和接收方交替发送心跳包,例如发送方先发送一个心跳包,接收方收到后立即发送响应,然后接收方再发送一个心跳包,发送方收到后立即发送响应,如此循环。
  6. 基于ACK确认:发送方在发送数据包后,等待一段时间后如果没有收到对应的ACK响应,则发送一个心跳包进行确认。接收方在收到心跳包后,只需要发送一个空的ACK响应即可。
    需要根据具体的应用场景和需求选择合适的心跳包机制,并根据实际情况进行调整和优化,以确保TCP连接的稳定性和可靠性。

24.UDP如何实现可靠传输
UDP是一种无连接的传输协议,不提供可靠传输机制。但是,可以通过在应用层实现一些机制来增加UDP的可靠性,以下是几种常见的方式:

  1. 应用层重传:在发送方和接收方的应用层实现重传机制。发送方在发送数据时,记录每个数据包的序号,并设置一个定时器。如果接收方没有收到某个数据包,可以向发送方发送一个请求重传的消息,发送方收到请求后,重新发送该数据包。
  2. 确认应答机制:接收方在收到数据包后,向发送方发送一个确认应答消息,告知发送方已经成功接收到数据。发送方在发送数据包后,等待一段时间,如果没有收到确认应答,则认为数据包丢失,进行重传。
  3. 校验和:在每个数据包中添加校验和,接收方在收到数据包后,根据校验和进行验证,如果校验和不匹配,则认为数据包有错误,要求发送方重新发送。
  4. 数据包排序:接收方在收到数据包后,根据序号对数据包进行排序,确保按照发送方的顺序进行处理。
  5. 流量控制:通过限制发送方的发送速率,防止接收方无法及时处理大量的数据包,从而提高可靠性。
    需要注意的是,这些机制都是在应用层实现的,而不是在UDP协议层实现的。因此,它们会增加一定的开销和复杂性。如果对可靠性要求较高,建议使用TCP协议,它提供了可靠的传输机制。

25.DNS域名系统。采用TCP还是UDP协议?为什么?
DNS(Domain Name System)域名系统在传输层可以使用TCP或UDP协议,具体使用哪种协议取决于所需的功能和性能要求。
一般情况下,DNS使用UDP协议进行域名解析。这是因为UDP是一种无连接的传输协议,它具有较低的开销和较快的传输速度。对于DNS来说,域名解析通常是一个简短的请求和响应过程,使用UDP可以减少传输的延迟和网络负载。
另一方面,由于UDP是无连接的,它不提供可靠的传输机制。这意味着在使用UDP时,可能会出现数据包丢失或乱序的情况。为了应对这种情况,DNS协议在应用层实现了一些机制,例如重传机制和超时机制,以确保数据的可靠传输。
然而,有些情况下,DNS可能会使用TCP协议。例如,当DNS的响应数据包超过UDP的最大长度限制(约为512字节)时,DNS会使用TCP进行传输。此外,某些特定的DNS查询类型,如区域传输(AXFR)和密钥传输(IXFR),也需要使用TCP协议。
综上所述,DNS通常使用UDP协议进行域名解析,因为UDP具有较低的延迟和较快的传输速度。但在某些情况下,DNS可能会使用TCP协议,以满足特定的功能和性能要求。

26.FTP协议(了解)
FTP(File Transfer Protocol)是一种用于在计算机网络上进行文件传输的协议。它使用客户端-服务器模型,其中客户端发送命令来请求文件传输,而服务器响应这些请求并执行相应的操作。
FTP协议使用两个独立的连接来进行通信:控制连接和数据连接。控制连接用于传输命令和响应,而数据连接用于实际的文件传输。
以下是FTP协议的一些特点和功能:

  1. 认证和授权:FTP协议支持用户名和密码的认证机制,以确保只有授权用户可以访问和传输文件。
  2. 目录操作:FTP协议提供了一系列命令,用于在服务器上进行目录操作,如列出目录内容、切换目录、创建目录等。
  3. 文件传输:FTP协议支持文件的上传和下载操作。客户端可以向服务器发送STOR命令来上传文件,服务器可以发送RETR命令来下载文件。
  4. 传输模式:FTP协议支持两种传输模式:主动模式和被动模式。在主动模式下,客户端使用一个随机的端口号来建立数据连接;在被动模式下,服务器使用一个随机的端口号来建立数据连接。
  5. 文件类型:FTP协议支持多种文件类型,包括ASCII文本文件和二进制文件。客户端可以使用TYPE命令来指定所需的文件类型。
  6. 文件权限和属性:FTP协议支持对文件权限和属性的操作,如更改文件的权限、修改文件名等。
    需要注意的是,FTP协议是基于明文传输的,不提供加密功能。因此,在使用FTP进行文件传输时,建议在网络环境中使用安全的通信协议,如FTP over TLS(FTPS)或SSH File Transfer Protocol(SFTP),以确保数据的安全性。

27.HTTP请求报文与响应报文首部结构
HTTP(Hypertext Transfer Protocol)是一种用于在客户端和服务器之间传输数据的协议。HTTP请求报文和响应报文都由首部(header)和消息体(body)组成。首部包含了关于请求或响应的元数据信息,而消息体则包含了实际的数据。
HTTP请求报文的首部结构如下:

  1. 请求行(Request Line):包含了请求的方法、URI(Uniform Resource Identifier)和HTTP版本。
  2. 请求头(Request Headers):包含了关于请求的附加信息,如Host、User-Agent、Accept等。
  3. 空行(Blank Line):用于分隔请求头和消息体,通常是一个空行。
  4. 消息体(Message Body):可选的,用于传输请求的数据,如表单数据、文件等。
    示例:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html, application/xhtml+xml

HTTP响应报文的首部结构如下:

  1. 状态行(Status Line):包含了响应的HTTP版本、状态码和状态消息。
  2. 响应头(Response Headers):包含了关于响应的附加信息,如Server、Content-Type、Content-Length等。
  3. 空行(Blank Line):用于分隔响应头和消息体,通常是一个空行。
  4. 消息体(Message Body):可选的,用于传输响应的数据,如HTML页面、图片等。
    示例:
HTTP/1.1 200 OK
Server: Apache/2.4.29
Content-Type: text/html; charset=UTF-8
Content-Length: 1234

<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>

需要注意的是,HTTP请求报文和响应报文的首部是由多个字段组成的,每个字段都以键值对的形式表示。字段之间使用冒号分隔,键值对之间使用换行符分隔。

28.HTTP1.0、HTTP1.1、HTTP2.0对比
HTTP(Hypertext Transfer Protocol)是一种用于在客户端和服务器之间传输数据的协议。以下是HTTP 1.0、HTTP 1.1和HTTP 2.0之间的一些主要区别和对比:

  1. 连接复用:
    • HTTP 1.0:每个请求都需要建立一个新的TCP连接,请求完成后立即关闭连接。
    • HTTP 1.1:引入了持久连接(persistent connection),允许多个请求和响应在同一个TCP连接上复用,减少了连接建立和关闭的开销。
    • HTTP 2.0:引入了多路复用(multiplexing),允许多个请求和响应同时在同一个TCP连接上进行,提高了并发性能。
  2. 请求和响应的顺序:
    • HTTP 1.0:请求和响应按照发送的顺序进行处理,即请求和响应的顺序是一一对应的。
    • HTTP 1.1:支持并发请求和响应,允许客户端发送多个请求而无需等待响应。
    • HTTP 2.0:通过多路复用,可以同时发送多个请求和响应,无需按照顺序进行。
  3. 头部压缩:
    • HTTP 1.0:不支持头部压缩,每个请求和响应都需要携带完整的头部信息。
    • HTTP 1.1:引入了头部压缩机制,使用了类似Gzip的压缩算法,减少了头部的传输大小。
    • HTTP 2.0:使用了HPACK压缩算法,更进一步地压缩了头部信息,减少了传输的数据量。
  4. 服务器推送:
    • HTTP 1.0和HTTP 1.1:服务器无法主动推送资源,只能等待客户端发送请求后才能响应。
    • HTTP 2.0:服务器可以主动推送资源,提前将客户端可能需要的资源推送给客户端,减少了额外的请求延迟。
  5. 加密和安全性:
    • HTTP 1.0和HTTP 1.1:不提供加密功能,数据传输是明文的。
    • HTTP 2.0:支持加密传输,可以使用TLS(Transport Layer Security)协议进行加密,提供了更好的安全性。
      需要注意的是,HTTP 2.0是在HTTP 1.1的基础上进行了优化和改进,而不是完全替代了HTTP 1.1。大多数现代浏览器和服务器都支持HTTP 1.1和HTTP 2.0,而HTTP 1.0已经逐渐被淘汰。使用哪个版本取决于服务器和客户端的支持情况。

29.HTTP与HTTPS对比
HTTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是用于在客户端和服务器之间传输数据的协议,它们之间的主要区别如下:
6. 安全性:

  • HTTP:数据传输是明文的,不提供加密功能,容易被窃听和篡改。
  • HTTPS:通过使用TLS(Transport Layer Security)协议进行加密,保护数据的安全性和完整性,防止窃听和篡改。
  1. 传输方式:
    • HTTP:使用明文传输,数据不经过加密处理。
    • HTTPS:使用加密传输,数据经过TLS加密处理后再传输。
  2. 默认端口:
    • HTTP:默认端口为80。
    • HTTPS:默认端口为443。
  3. 证书要求:
    • HTTP:不需要证书。
    • HTTPS:需要使用SSL/TLS证书,由可信的证书颁发机构(CA)进行签发。
  4. 连接建立过程:
  • HTTP:建立TCP连接后直接发送请求。
  • HTTPS:建立TCP连接后进行SSL/TLS握手,验证服务器身份和协商加密算法,然后再发送请求。
  1. 性能:
  • HTTP:由于不需要进行加密和解密的操作,性能相对较高。
  • HTTPS:由于需要进行加密和解密的操作,会增加一定的计算和传输开销,性能相对较低。
    需要注意的是,HTTPS是在HTTP的基础上加入了TLS/SSL协议进行加密和认证,提供了更高的安全性。在现代互联网中,许多网站都采用了HTTPS来保护用户的隐私和数据安全。使用哪种协议取决于网站的需求和安全性要求。

30.HTTPS加密流程
HTTPS使用了TLS(Transport Layer Security)协议来进行加密和认证,其加密流程如下:

  1. 客户端发送HTTPS请求给服务器,请求建立安全连接。
  2. 服务器收到请求后,将自己的数字证书(包含公钥)发送给客户端。
  3. 客户端收到服务器的数字证书后,首先验证证书的合法性和有效性。验证包括检查证书的颁发机构是否可信、证书是否过期等。
  4. 客户端使用证书中的公钥对一个随机生成的对称密钥(称为会话密钥)进行加密,并将加密后的会话密钥发送给服务器。
  5. 服务器收到加密后的会话密钥后,使用自己的私钥进行解密,得到会话密钥。
  6. 客户端和服务器都使用会话密钥来进行对称加密,保证数据的机密性和完整性。
  7. 安全连接建立后,客户端和服务器可以进行加密通信,互相发送加密的请求和响应。
    需要注意的是,TLS协议还包括了身份认证和密钥协商的过程。服务器通过数字证书来证明自己的身份,而客户端可以选择是否验证服务器的身份。密钥协商过程使用了公钥加密和对称加密的结合,保证了密钥的安全性和传输的效率。
    通过使用TLS协议,HTTPS提供了更高的安全性,保护了用户的隐私和数据的机密性。同时,HTTPS也能够防止数据被篡改和窃听,提供了更可靠的通信环境。

31.方法:GET、HEAD、POST、PUT、DELETE
HTTP协议定义了多种请求方法(也称为HTTP动词或HTTP动作),用于指定客户端对服务器资源的操作方式。以下是常见的HTTP请求方法:

  1. GET:用于请求获取指定资源的内容。客户端通过GET方法向服务器发送请求,服务器将返回请求的资源内容作为响应。
  2. HEAD:与GET方法类似,但服务器不返回实际的资源内容,只返回响应头信息。主要用于获取资源的元数据,如文件大小、修改时间等。
  3. POST:用于向服务器提交数据,请求服务器接受并处理请求中包含的实体数据。通常用于创建新资源、提交表单数据等。
  4. PUT:用于向服务器上传或替换指定资源的内容。客户端通过PUT方法向服务器发送请求,服务器将根据请求中的资源标识符来更新或创建资源。
  5. DELETE:用于请求服务器删除指定的资源。客户端通过DELETE方法向服务器发送请求,服务器将删除请求中指定的资源。
    除了上述常见的请求方法,还有一些其他的HTTP请求方法,如OPTIONS、TRACE、CONNECT等,它们用于特定的操作或功能。
    需要注意的是,不同的请求方法在语义上有所区别,服务器对不同的请求方法可能有不同的处理逻辑。在设计和开发Web应用程序时,需要根据具体的需求和业务逻辑选择合适的请求方法。

32.状态码:1、2**、3**、4**、5****
HTTP状态码用于表示服务器对请求的处理结果,按照分类可以分为以下几个范围:
1xx(Informational):表示请求已被接收,继续处理。

  • 100 Continue:服务器已收到请求的部分内容,客户端可以继续发送剩余的请求。
  • 101 Switching Protocols:服务器已根据客户端的要求,切换协议(例如从HTTP到WebSocket)。
    2xx(Success):表示请求已成功被服务器接收、理解和处理。
  • 200 OK:请求成功,服务器返回对应的资源。
  • 201 Created:请求成功,服务器创建了新的资源。
  • 202 Accepted:服务器已接受请求,但尚未进行处理。
  • 204 No Content:服务器已成功处理请求,但没有返回任何实体内容。
    3xx(Redirection):表示客户端需要进行附加操作才能完成请求。
  • 301 Moved Permanently:永久重定向,请求的资源已被分配到新的URL。
  • 302 Found:临时重定向,请求的资源暂时移动到新的URL。
  • 304 Not Modified:客户端的缓存资源可用,表示请求的资源未被修改,可以直接使用缓存。
    4xx(Client Errors):表示客户端的请求有错误。
  • 400 Bad Request:请求有语法错误,服务器无法理解。
  • 401 Unauthorized:请求需要身份验证。
  • 403 Forbidden:服务器拒绝请求的访问权限。
  • 404 Not Found:请求的资源不存在。
    5xx(Server Errors):表示服务器端发生错误。
  • 500 Internal Server Error:服务器内部错误,无法完成请求。
  • 502 Bad Gateway:作为网关或代理的服务器从上游服务器接收到无效响应。
  • 503 Service Unavailable:服务器暂时无法处理请求,通常是由于过载或维护。
    状态码用于客户端和服务器之间的通信,以便更好地了解请求和响应的处理结果。根据不同的状态码,可以进行相应的错误处理或者进行重定向等操作。

33.cookie与session区别
Cookie和Session是用于在Web应用程序中跟踪用户状态的机制,它们之间有以下几个区别:

  1. 存储位置:Cookie是存储在客户端(浏览器)中的小型文本文件,而Session数据存储在服务器端。
  2. 数据安全性:由于Cookie是存储在客户端,所以它的数据可以被用户篡改或者窃取,因此Cookie的安全性较低。而Session数据存储在服务器端,对用户是不可见的,相对来说更安全。
  3. 存储容量:Cookie的存储容量有限,一般为几KB,因此适合存储较小的数据。而Session数据存储在服务器端,理论上没有容量限制。
  4. 生命周期:Cookie可以设置过期时间,可以在客户端保留一段时间。而Session数据的生命周期由服务器控制,通常在用户关闭浏览器或者一段时间不活动后过期。
  5. 跨域支持:Cookie可以设置为跨域访问,即在不同的域名下共享。而Session数据通常只在同一域名下共享。
  6. 性能开销:由于Session数据存储在服务器端,每次请求都需要在服务器端进行读写操作,会增加服务器的负载。而Cookie是存储在客户端,对服务器的性能影响较小。
    根据实际需求和安全性要求,开发者可以选择使用Cookie或Session来管理用户状态。一般情况下,Cookie用于存储较小的、不敏感的数据,而Session用于存储较大的、敏感的数据。

34.输入一个URL到显示页面的流程(越详细越好,搞明白这个,网络这块就差不多了)
以下是从输入URL到显示页面的详细流程:

  1. 用户在浏览器的地址栏中输入URL(统一资源定位符)。
  2. 浏览器解析URL,提取出协议(例如HTTP、HTTPS)、主机名(例如www.example.com)和路径(例如/index.html)等信息。
  3. 浏览器根据主机名解析出服务器的IP地址,通过DNS(域名系统)进行域名解析。
  4. 浏览器与服务器建立TCP(传输控制协议)连接。这个过程通常是通过三次握手来建立可靠的连接。
  5. 浏览器向服务器发送HTTP请求。请求中包含请求方法(例如GET、POST)、路径、协议版本、请求头(例如Accept、User-Agent)和请求体(对于POST请求)等信息。
  6. 服务器接收到请求后,根据路径和其他请求信息,找到对应的资源文件或者处理程序。
  7. 服务器处理请求,可能会进行一些后端逻辑处理,如数据库查询、业务逻辑处理等。
  8. 服务器生成HTTP响应,包括状态码、响应头(例如Content-Type、Content-Length)和响应体(HTML、图片等)等信息。
  9. 服务器将HTTP响应发送回浏览器。
  10. 浏览器接收到响应后,根据响应头中的Content-Type确定响应数据的类型。
  11. 如果响应数据是HTML文件,浏览器开始解析HTML文档,构建DOM(文档对象模型)树。
  12. 浏览器根据DOM树和CSS样式表进行渲染,生成页面布局。
  13. 如果HTML文档中包含JavaScript代码,浏览器会执行JavaScript代码,可能会修改DOM树和样式,或者进行其他操作。
  14. 浏览器将渲染后的页面显示给用户。
    以上是一个简化的流程,实际上还涉及到很多细节和优化。例如,浏览器可能会进行缓存处理,服务器可能会进行负载均衡和反向代理等。了解这个流程可以帮助我们更好地理解Web应用程序的工作原理,以及在开发和调试过程中可能遇到的问题。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值