TCP IP 网络协议入门

An Intro to TCP IP

Posted by Kylin on April 1, 2023

[TOC]

基础知识

TPC IP 简介

TCP/IP(Transmission Control Protocol/Internet Protocol)是传输控制协议和网络协议的简称,它定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。

TCP/IP 不是一个协议,而是一个协议族的统称,里面包括了 IP 协议、ICMP 协议、TCP 协议、以及 http、ftp、pop3 协议等。网络中的计算机都采用这套协议族进行互联。

  • 网络协议栈结构上OSI模型和TCP/IP模型协议族的结构则稍有不同,它们之间的层次结构有如图对应关系:

1548669082626

可见 TCP/IP 被分为 4 层,每层承担的任务不一样,各层的协议的工作方式也不一样,每层封装上层数据的方式也不一样:

  • 应用层:应用程序通过这一层访问网络,常见 FTP、HTTP、DNS 和 TELNET 协议;
  • 传输层:TCP 协议和 UDP 协议;
  • 网络层:IP 协议,ARP、RARP 协议,ICMP 协议等;
  • 网络接口层:是 TCP/IP 协议的基层,负责数据帧的发送和接收。

概念

查看ip地址
ifconfig | grep "inet"

# windows 下用 ipconfig,以上是类unix系统的命令
查看域名对应的ip地址
nslookup github.com
ping github.com
常用协议对应端口号

端口号有 0 ~ 65535 的编号,其中:

  • 编号 0 ~ 1023 为 系统端口号 ,这些端口号可以在网址 www.iana.org 查询到,它们被指派给了 TCP/IP 最重要的一些应用程序,以下是一些常见的系统端口号:
协议 SSH FTP Telnet SMTP TFTP HTTP SNMP Ping
端口号 22 20 和 21 23 25 69 80 161 使用 ICMP, 无具体端口号
  • 编号 1024 ~ 49151 为登记端口号,为没有系统端口号的应用程序使用,使用这类端口号必须在 IANA 按规定手续登记,以防止重复。
  • 编号 49152 ~ 65535 为短暂端口号,是留给客户进程选择暂时使用的,使用结束后,这类端口号会被放开以供其它程序使用。
# 查看监听端口号
netstat -luant
Protocol Data Unit

1548670748600

物理层 (一层) PDU 指数据位 (Bit)

数据链路层 (二层) PDU 指数据帧 (Frame)

网络层 (三层) PDU 指数据包 (Packet)

传输层 (四层) PDU 指数据段 (Segment)

第五层以上为数据(data)

RFC

RFC (Request for Comment) 文档是所有以太网协议的正式 标准, 并在其官网上面公布, 由 IETF 标准协会制定。大量的 RFC 并不是正式的标准, 出版的目的只是为了提供信息。RFC 的篇幅不一, 从几页到几百页不等。每一种协议都用一个数字 来标识, 如 RFC 3720 是 ISCSI 协议的标准, 数字越大意味着 RFC 的内容越新或者是对应的协议(标准)出现的比较晩。

MTU

为了提供足够快的响应时间, 以太网和 IEEE802.3 对数据帧长度都有限制, 其最大值分别为 1500 字节和 1492 字节, 链路 层的这个特性称作 MTU, 即最大传输单元。

查看MTU

netstat -in

IP网际协议

IP 网际协议提供不可靠无连接服务

不可靠(unreliable):IP 协议不能保证数据报能成功地到 达目的地, 它仅提供传输服务。当发生某种错误时, IP 协 议会丢弃该数据报。传输的可靠性全由上层协议来提供。

无连接(connectionless):IP 协议对每个数据报的处理 是相互独立的。这也说明, IP 数据报可以不按发送顺序接 收。如果发送方向接收方发送了两个连续的数据报(先是 $A$, 然后是 B), 每个数据报可以选择不同的路线, 因此 $B$ 可能在 $A$ 到达之前先到达。

IP数据报

1548754469956

普通的 IP 数据报的报头长度 20 字节(除非有选项字段),各个部分的作用:

  • 版本号:4 位,用于标明 IP 版本号,0100 表示 IPv4,0110 表示 IPv6。目前常见的是 IPv4。
  • 首部长度:4 位,表示 IP 报头长度,包括选项字段。
  • 服务类型(TOS):分别有:最小时延、最大吞吐量、最高可靠性、最小花费 4 种服务,如下图所示。4 个标识位只能有一个被置为 1。
  • 总长度:16 位,报头长度加上数据部分长度,便是数据报的总长度。IP 数据报最长可达 65535 字节。
  • 标识:16 位,接收方根据分片中的标识字段相不相同来判断这些分片是不是同一个数据报的分片,从而进行分片的重组。通常每发送一份报文它的值就会加 1。
  • 标志:3 位,用于标识数据报是否分片。其中的第 2 位是不分段(DF)位。当 DF 位被设置为 1 时,则不对数据报进行分段处理;第 3 位是分段(MF)位,除了最后一个分段的 MF 位被设置为 0 外,其他的分段的 MF 位均设置为 1。
  • 偏移:13 位,在接收方进行数据报重组时用来标识分片的顺序。
  • 生存时间(TTL):8 位,用于设置数据报可以经过的最多的路由器个数。TTL 的初始值由源主机设置(通常为 32 或 64),每经过一个处理它的路由器,TTL 值减 1。如果一个数据报的 TTL 值被减至 0,它将被丢弃。
  • 协议:8 位,用来标识是哪个协议向 IP 传送数据。ICMP 为 1,IGMP 为 2,TCP 为 6,UDP 为 17,GRE 为 47,ESP 为 50。
  • 首部校验和:根据 IP 首部计算的校验和码。
  • 源 IP 和目的 IP :数据报头还会包含该数据报的发送方 IP 和接收方 IP。
  • 选项:是数据报中的一个可变长、可选的信息,不常用,多用于安全、军事等领域。
使用 tcpdump 抓包
sudo tcpdump -ntx -c 1

#####################
-n : 显示 IP 地址而非域名地址
-t : 不显示时间戳
-x : 以十六进制显示包内内容
-c : tcpdump 将在接受到几个数据包后退出
  • 分析

b54e2a5e0365c8d0131551ab667dc0f9-0

  • 首先看到开头的 192.168.42.3.3001 > 172.16.2.250.44632 代表的是源 ip 为 192.168.42.3,端口 3001,目的 ip 为 172.16.2.250,端口 44632

    然后看到 0x0000 那行:

    • 协议版本: 0x4 表示的是协议版本为 IPv4
    • 首部长度: 0x55*4=20,表示 IP 报头长度为 20 字节。一个字节通常等于 8 位,所以这里可以知道 IP 报头为 45002a02
    • TOS 服务类型:0x00,意味着是一般服务;
    • 总长度:0x0136,换算下来为 310 字节;
    • 标识:0x172a
    • 3bit 标志 + 13bit 片偏移:0x4000
    • 生存时间:0x40,值为 64;
    • 协议:0x06,代表 TCP 协议;
    • 首部校验和:0x88e2

IP路由选择

IP 层在内存中有一个路由表(输入命令 route -n 可以查看路由表),当收到一份数据报并进行发送时,都要对该表进行搜索:

  • 搜索路由表,如果能找到和目的 IP 地址完全一致的主机,则将 IP 数据报发向该主机;
  • 搜索路由表,如果匹配主机失败,则匹配同子网的路由器(这需要子网掩码的协助)。如果找到路由器,则将该 IP 数据报发向该路由器;
  • 搜索路由表,如果匹配同子网路由器失败,则匹配同网络号路由器,如果找到路由器,则将该 IP 数据报发向该路由器;
  • 如果以上都失败了,就搜索默认路由,如果默认路由存在,则发报;
  • 如果都失败了,就丢掉这个包;
  • 接收到数据报的路由器再按照它自己的路由表继续转发,直到数据报被转发到目的主机;
  • 如果在转发过程中,IP 数据报的 TTL(生命周期)已经被减为 0,则该 IP 数据报就被抛弃。
查看路由表
route -n
追踪路由过程
sudo apt-get update
sudo apt-get install -y traceroute

# 设置跳数为 8
traceroute -m 8 www.shiyanlou.com
# 探测包个数设为 4
traceroute -q 4 www.shiyanlou.com
# 显示 IP 地址,不查主机名
traceroute -n www.shiyanlou.com

#### NAT

当你用 ifconfig 查看 IP 地址时,有时你会发现自己的 IP 地址是这样的—192.168.X.X 或 172.16.X.X。这是 C 类网和 B 类网的私有地址,就是俗称的内网 IP。这是因为你的路由器采用了 NAT 技术。

NAT(Network Address Translation,网络地址转换)是 1994 年提出的。当在专用网内部的一些主机本来已经分配到了内网 IP 地址,但现在又想和因特网上的主机通信时,NAT 技术将其内网 IP 地址转换成全球 IP 地址,然后与因特网连接,也就是说,内网的数台主机使用了同一个全球 IP 地址在上网。

查看内网地址
ifconfig eth0

网络层其他协议

1548900390889

ARP(Address Resolution Protocol)

当主机通过数据链路发送数据的时候,IP 数据报会先被封装为一个数据帧,而MAC 地址会被添加到数据帧的报头(链路层介绍时已讲过)。

ARP 便是在这个过程中通过目标主机的 IP 地址,查询目标主机的 MAC 地址。

ARP原理

在你的电脑和路由器中都有一个 ARP 缓存表,其中保存的是近期(20 分钟)与自己有过通信的主机的 IP 地址与 MAC 地址的对应关系。

ARP 缓存表使用过程:

  • 当主机要发送一个 IP 数据报的时候,会首先查询一下自己的 ARP 缓存表;
  • 如果在 ARP 缓存表中找到对应的 MAC 地址,则将 IP 数据报封装为数据帧,把 MAC 地址放在帧首部,发送数据帧;
  • 如果查询的 IP-MAC 值对不存在,那么主机就向网络中广播发送一个 ARP 请求数据帧,ARP 请求中包含待查询 IP 地址;
  • 网络内所有收到 ARP 请求的主机查询自己的 IP 地址,如果发现自己符合条件,就回复一个 ARP 应答数据帧,其中包含自己的 MAC 地址;
  • 收到 ARP 应答后,主机将其 IP - MAC 对应信息存入自己的 ARP 缓存,然后再据此封装 IP 数据报,再发送数据帧。

可以通过命令 arp -a 查看 ARP 缓存表(表项记录 20 分钟超时),这里介绍几个主要选项:

arp
arp -a
arp -v

#######################
-a	显示 ARP 高速缓存中的所有内容
-d	从 ARP 缓冲区中删除指定主机的 ARP 条目
-s	设置指定的主机的 IP 地址与 MAC 地址的静态映射
-v	显示详细的 arp 缓冲区条目,包括缓冲区条目的统计信息
ARP 代理

如果 ARP 请求是从一个网络上的主机发往另一个网络上的主机,那么连接这两个网络的路由器就可以回答该 ARP 请求,这个过程称作代理 ARP(Proxy ARP)。

当连接这两个网络的路由器收到该 ARP 请求时,它会发现自己有通向目的主机的路径,随后它会将自己(路由器)的 MAC 地址回复给源主机。源主机会认为路由器的 MAC 地址就是目的主机的 MAC 地址,而对于随后发来的数据帧,路由器会转发到它后面真实 MAC 地址的目的主机。

两个物理网络之间的路由器可以使这两个网络彼此透明化,在这种情况下,只要路由器设置成一个 ARP 代理,以响应一个网络到另一个网络主机的 ARP 请求,两个物理网络就可以使用相同的网络号。

ARP 欺骗

从 ARP 代理的原理可以看出来:IP - MAC 的对应信息很容易被伪造!黑客可以伪造 ARP 应答数据帧而欺骗 ARP 请求者,从而达到截获数据的目的。

RARP(Reverse Address Resolution Protocol)

听名字就知道,RARP 与 ARP 是相反的关系,用于将 MAC 地址转换为 IP 地址。对应于 ARP,RARP 请求以广播方式传送,而 RARP 应答一般是单播传送的。

某些设备,比如无盘机在启动时可能不知道自己的 IP 地址,它们可以将自己的 MAC 地址使用 RARP 请求广播出去,RARP 服务器就会响应并回复无盘机的 IP 地址。

RARP 在目前的应用中已极少被使用,不再赘述了。

ICMP(Internet Control Message Protocol)

通信过程中发生各种问题时,ICMP 将问题反馈,通过这些信息,管理者可以对所发生的问题作出诊断,然后采取适当的措施去解决它。

ICMP 报文由 8 位错误类型、8 位条件代码和 16 位校验和组成,被封装在一个 IP 数据报中:

报文的类型字段可以有 15 个不同的值,以便描述特定类型的 ICMP 报文,代码字段的值进一步描述不同的条件,各报文类型描述可参考 ICMP

也有一些出现差错而不产生 ICMP 报文的情况,比如:

  • ICMP 差错报文;
  • 目的地址是广播或多播地址;
  • 作为链路层广播的数据报;
  • 不是 IP 分片的第一片;
  • 源地址不是单个主机的数据报(源不能为零地址、环回地址、广播多播地址)。

ping 程序和 traceroute 程序是两个常见的基于 ICMP 协议的工具。

ping 程序

ping 程序是对两台主机之间连通性进行测试的基本工具,它只是利用 ICMP 回显请求和回显应答报文,而不用经过传输层(TCP/UDP)。

ping 程序通过在 ICMP 报文数据中存放发送请求的时间值来计算往返时间,当应答返回时,用当前时间减去存放在 ICMP 报文中的时间值,即是往返时间。

ping 程序使用方法为 ping IP 地址,ping 命令还可以加上参数,实现更多的功能:

  • -n 只输出数值;
  • -q 不显示任何传送封包的信息,只显示最后的结果;
  • -r 忽略普通的 Routing Table,直接将数据包送到远端主机上,通常是查看本机的网络接口是否有问题;
  • -R 记录路由过程;
  • -v 详细显示指令的执行过程;
  • -c 数目:在发送指定数目的包后停止;
  • -i 秒数:设定间隔几秒传送一个网络封包给一台机器,预设值是一秒送一次;
  • -t 存活数值:设置存活数值 TTL 的大小。
sudo tcpdump -nnvXSs 0 -c2 icmp

#另一个终端
ping -c1 mirrors.cloud.aliyuncs.com 
TTL值和目标操作系统判断

TTL 是 Time To Live 的缩写,该字段指定 IP 包被路由器丢弃之前允许通过的最大网段数量。可以去回顾一下上节的 IP 报文结构图。

TTL 是 IPv4 包头的一个 8 bit 字段,它的作用是限制 IP 数据包在计算机网络中的存在时间,即 IP 数据包在计算机网络中可以转发的最大条数。

假如没有 TTL 字段,网络中的 IP 包将越来越多造成网络阻塞,TTL 避免 IP 包在网络中的无限循环和收发,节省了网络资源,并能使 IP 包的发送者能收到告警消息。

ping 命令会返回一个 TTL 值,我们可以使用它来判断目标的操作系统类型。 常见操作系统缺省 TTL 值如下:

  • UNIX TTL: 255;
  • Linux TTL: 64;
  • WINDOWS 95/98 TTL: 32;
  • Windows NT 4.0/2000/XP/2003/7/8/10 TTL:128。
traceroute 程序

traceroute 程序是用来侦测主机到目的主机之间所经路由情况的重要工具。刚才 ping 程序中讲过,带 -R参数的 ping 命令也可以记录路由过程,但是因为 IP 数据报头的长度限制(最多能保存 9 个 IP 地址),ping 不能完全的记录下所经过的路由器,traceroute 正好就填补了这个缺憾。

traceroute 工作原理
  • 它发送一份 TTL 为 1 的 IP 数据报给目的主机,经过第一个路由器时,TTL 值被减为 0,则第一个路由器丢弃该数据报,并返回一份超时 ICMP 报文,于此得到了路径中第一个路由器的地址;
  • 然后再发送一份 TTL 值为 2 的数据报,便可得到第二个路由器的地址;
  • 以此类推,一直到到达目的主机为止,这样便记录下了路径上所有的路由 IP。
traceroute -n www.github.com

IGMP(Internet Group Management Protocol)

IGMP 是用于管理多播组成员的一种协议,它的作用在于:让其它所有需要知道自己处于哪个多播组的主机和路由器知道自己的状态。只要某一个多播组还有一台主机,多播路由器就会把数据传输出去,这样接受方就会通过网卡过滤功能来得到自己想要的数据。

为了知道多播组的信息,多播路由器需要定时的发送 IGMP 查询,各个多播组里面的主机要根据查询来回复自己的状态。路由器来决定有几个多播组,自己要对某一个多播组发送什么样的数据。

UDP协议

UDP概述

UDP(User Datagram Protocol)用户数据报协议,它只在 IP 数据报服务之上增加了很少一点功能,它的主要特点有:

  • UDP 是无连接的,发送数据之前不需要建立连接(而 TCP 需要),减少了开销和时延。
  • UDP尽最大努力交付,不保证交付可靠性。
  • UDP 是面向报文的,对于从应用层交付下来的 IP 数据报,只做很简单的封装(8 字节 UDP 报头),首部开销小。
  • UDP 没有拥塞控制,出现网络拥塞时发送方也不会降低发送速率。这种特性对某些实时应用是很重要的,比如 IP 电话,视频会议等,它们允许拥塞时丢失一些数据,因为如果不抛弃这些数据,极可能造成时延的累积。
  • UDP 支持一对一、一对多、多对一和多对多的交互通信。

1548917382675

UDP报文

UDP 数据报可分为两部分:UDP 报头和数据部分。其中数据部分是应用层交付下来的数据。UDP 报头总共 8 字节,而这 8 字节又分为 4 个字段:

1548918088748

  • 源端口:2 字节,在对方需要回信时可用,不需要时可以全 0;
  • 目的端口:2 字节,必须,也是最重要的字段;
  • 长度:2 字节,长度值包括报头和数据部分;
  • 校验和:2 字节,用于检验 UDP 数据报在传输过程中是否有出错,有错就丢弃。

tcpdump抓取UDP报文

wget https://labfile.oss-internal.aliyuncs.com/courses/98/test.c
gcc -o test test.c

sudo tcpdump -vvv -X udp port 7777
./test

#####################
sudo:以管理员权限运行 tcpdump 命令
tcpdump:一个常用的网络分析工具,用于捕获和分析网络流量
-vvv:设置 tcpdump 为详细模式,输出更多的信息
-X:设置 tcpdump 以十六进制格式输出捕获的数据包
udp:指定捕获 UDP 协议的数据包
port 7777:指定捕获目标端口号为 7777,即只捕获发送至该端口的数据包。

d3b20dde790726105e135b04d0e7d794-0

蓝色框为 16 进制目的端口,绿色框为 16 进制目的 IP,红色框为 20 字节 IP 报头,橘色下划线为 8 字节 UDP 报头,红色下划线为 hello 的 ASCII 码。

45000101 都是 IP 报头,IP 报文在之前已经讲过,这里就不赘述了。后面的部分就是 UDP 报文。

我们知道 UDP 报头一共 8 字节,所以从 eb39ac82 是 UDP 报头的部分。

  • eb39:源端口,2 字节,换成十进制也就是 32830
  • 1e61:目的端口,2 字节,十进制为 7777
  • 001c:包长度,单位为字节,换为十进制可知包长度为 28 字节
  • ac82:校验和

后面的就是数据内容的 ASCII 码。

TCP协议

TCP概述

  • TCP 提供 可靠的 数据传输服务,TCP 是 面向连接的 。应用程序在使用 TCP 通信之前,先要建立连接,这是一个类似“打电话”的过程,通信结束后还要“挂电话”。
  • TCP 连接是 点对点 的,一条 TCP 连接只能连接两个端点。
  • TCP 提供可靠传输,无差错、不丢失、不重复、按顺序。
  • TCP 提供 全双工 通信,允许通信双方任何时候都能发送数据,因为 TCP 连接的两端都设有发送缓存和接收缓存。
  • TCP 面向 字节流 。TCP 并不知道所传输的数据的含义,仅把数据看作一连串的字节序列,它也不保证接收方收到的数据块和发送方发出的数据块具有大小对应关系。

TCP报文段

TCP 报文段的报头有前 20 字节的固定部分,后面 4n 字节是根据需要而添加的字段。如图则是 TCP 报文段结构:

1548921882697

  • 源端口和目的端口:各占 2 个字节,分别写入源端口号和目的端口号。这和 UDP 报头有类似之处,因为都是传输层协议。
  • 序号:占 4 字节序,序号范围[0,2^32-1],序号增加到 2^32-1 后,下个序号又回到 0。TCP 是面向字节流的,通过 TCP 传送的字节流中的每个字节都按顺序编号,而报头中的序号字段值则指的是本报文段数据的第一个字节的序号
  • 确认序号:占 4 字节,期望收到对方下个报文段的第一个数据字节的序号。
  • 数据偏移:占 4 位,指 TCP 报文段的报头长度,包括固定的 20 字节和选项字段。
  • 保留:占 6 位,保留为今后使用,目前为 0。
  • 控制位:共有 6 个控制位,说明本报文的性质,意义如下:
    • URG 紧急:当 URG=1 时,它告诉系统此报文中有紧急数据,应优先传送(比如紧急关闭),这要与紧急指针字段配合使用。
    • ACK 确认:仅当 ACK=1 时确认号字段才有效。建立 TCP 连接后,所有报文段都必须把 ACK 字段置为 1。
    • PSH 推送:若 TCP 连接的一端希望另一端立即响应,PSH 字段便可以“催促”对方,不再等到缓存区填满才发送。
    • RST复位:若 TCP 连接出现严重差错,RST 置为 1,断开 TCP 连接,再重新建立连接。
    • SYN 同步:用于建立和释放连接,稍后会详细介绍。
    • FIN 终止:用于释放连接,当 FIN=1,表明发送方已经发送完毕,要求释放 TCP 连接。
  • 窗口:占 2 个字节。窗口值是指发送者自己的接收窗口大小,因为接收缓存的空间有限。
  • 检验和:2 个字节。和 UDP 报文一样,有一个检验和,用于检查报文是否在传输过程中出差错。
  • 紧急指针:2 字节。当 URG=1 时才有效,指出本报文段紧急数据的字节数。
  • 选项:长度可变,最长可达 40 字节。具体的选项字段,需要时再做介绍。
使用 tcpdump 抓包
sudo tcpdump -ntx -c 1

#####################
-n : 显示 IP 地址而非域名地址
-t : 不显示时间戳
-x : 以十六进制显示包内内容
-c : tcpdump 将在接受到几个数据包后退出
  • 分析

b54e2a5e0365c8d0131551ab667dc0f9-0

源端口:0x170d,转换为十进制为 5901。

目的端口:0x9d86,即为 40326。

序号:0xba42638b,即为 3124913035,这和图中开头的 seq 是一致的。

确认序号:0x4c1ad749,即为 1276827465,这和图中开头的 ack 是一致的。

数据偏移:0x88*4=32B

其他可依次类推。

三次握手和四次挥手

连接建立

在传输 TCP 报文段之前先要创建连接,发起连接的一方被称为客户端,而响应连接请求的一方被称为服务端,而这个创建连接的过程被称为三次握手

1548922782588

  • 客户端发出请求连接报文段,其中报头控制位 SYN=1,初始序号 seq=x。客户端进入 SYN-SENT(同步已发送)状态。
  • 服务端收到请求报文段后,向客户端发送确认报文段。确认报文段的首部中 SYN=1,ACK=1,确认号是 ack=x+1,同时为自己选择一个初始序号 seq=y。服务端进入 SYN-RCVD(同步收到)状态。
  • 客户端收到服务端的确认报文段后,还要给服务端发送一个确认报文段。这个报文段中 ACK=1,确认号 ack=y+1,而自己的序号 seq=x+1。这个报文段已经可以携带数据,如果不携带数据则不消耗序号,则下一个报文段序号仍为 seq=x+1

至此 TCP 连接已经建立,客户端进入 ESTABLISHED(已建立连接)状态,当服务端收到确认后,也进入 ESTABLISHED 状态,它们之间便可以正式传输数据了。

连接释放

1548923334867

  • 此时 TCP 连接两端都还处于 ESTABLISHED 状态,客户端停止发送数据,并发出一个 FIN 报文段。首部 FIN=1,序号 seq=u(u 等于客户端传输数据最后一字节的序号加 1)。客户端进入 FIN-WAIT-1(终止等待 1)状态。
  • 服务端回复确认报文段,确认号 ack=u+1,序号 seq=v(v 等于服务端传输数据最后一字节的序号加 1),服务端进入 CLOSE-WAIT(关闭等待)状态。现在 TCP 连接处于半开半闭状态,服务端如果继续发送数据,客户端依然接收。
  • 客户端收到确认报文,进入 FIN-WAIT-2 状态,服务端发送完数据后,发出 FIN 报文段,FIN=1,确认号 ack=u+1,然后进入 LAST-ACK(最后确认)状态。
  • 客户端回复确认报文段,ACK=1,确认号 ack=w+1(w 为半开半闭状态时,收到的最后一个字节数据的编号) ,序号 seq=u+1,然后进入 TIME-WAIT(时间等待)状态。

注意此时连接还没有释放,需要时间等待状态结束后(4 分钟)连接两端才会 CLOSED。设置时间等待是因为,有可能最后一个确认报文丢失而需要重传。

tcpdump抓包测试

查看数据包统计信息
netstat -s

返回:主动开放的连接数,被动开放的连接数,失败的连接尝试,重置连接数,当前连接数,接收的 分段数,发送的分段数,重新传输的分段数。

三次握手抓包测试
sudo tcpdump -S host 192.168.42.3 and 121.40.227.60

注意:此处的 192.168.42.3 要根据你自己的环境修改,为内网 ip,可以通过 ifconfig eth0 查看。121.40.227.60 是蓝桥云课的网址,需要通过 nslookup www.lanqiao.cn 命令查询最新的 IP 地址。

命令目的为抓取本机到 www.lanqiao.cn 的数据包;

-S 参数的目的是获得 ack 的绝对值。

然后使用浏览器访问 www.lanqiao.cn。再回到终端,可以看到如下输出:

7d05c2b33722f3a2a629127bc5740894-0

输出中展示了三次握手的过程。红色为第一次,黄框是第二次,绿框是第三次,试着根据上面介绍的握手过程来对照 seq 和 ack 值的变化。

抓取 TCP 报文段

针对这次实验,需要下载对应的代码文件,是基于 TCP 的聊天小程序,分为 server(服务端—)和 client(客户端):

wget https://labfile.oss-internal.aliyuncs.com/courses/98/client.c
wget https://labfile.oss-internal.aliyuncs.com/courses/98/server.c
gcc -o server server.c
gcc -o client client.c

编译完成后先不要运行,先打开 tcpdump,使用命令安装并运行 tcpdump:

sudo apt-get update
sudo apt-get install tcpdump
sudo tcpdump -vvv -X -i lo tcp port 7777

新开一个终端,运行 server 程序:

./server 127.0.0.1

然后再新开第三个终端,运行 client 程序:

./client 127.0.0.1

现在,使用 client 和 server 聊天,轮流互发几条简短的消息(比如 hello、hi、wei 之类的)便可以关闭 client 和 server,回到运行 tcpdump 的终端查看抓取的报文段内容:

tcp-6-08

概念

  • TCP 可靠传输的实现?

当 TCP 发出一个报文段后,它启动一个定时器,等待目的端确认收到这个报文段,如果不能及时收到一个确认,将重发这个报文段。这就是稍后介绍的超时重传

应用层协议

DNS

在浏览器中输入一个域名后,会有 DNS 服务器将域名解析为对应的 IP 地址。注意这和网络层的 ARP 协议的不同之处:DNS 提供的是域名与 IP 地址的对应关系,而 ARP 提供的是 IP 地址和 MAC 地址的对应关系。

DNS服务器
  • 根 DNS 服务器 :全世界共有 13 台根域名服务器,编号 A 到 M,其中大部分位于美国。
  • 顶级(TLD)DNS 服务器 :负责如 com、org、edu 等顶级域名和所有国家的顶级域名(如 cn 、uk 、jp)。
  • 权威 DNS 服务器 :大型组织、大学、企业的域名解析服务。
  • 本地 DNS 服务器 :通常与我们主机最近的 DNS 服务器。
域名解析过程
  • 主机向本地域名服务器的查询过程是递归查询

1548998945361.png

host命令

在 linux 系统中,可以用 host 命令进行 DNS 查询,查看一个指定域名的 IP,比如要查询 mirrors.aliyuncs.com 的 IP 地址:

host mirrors.aliyuncs.com
DNS 报文

主机向 DNS 服务器发出的查询叫做DNS 报文,问答报文的内容,都是 IP 和域名的对应信息,问题中包含域名,类型,类信息,回答中包含指针,类型,类,TTL,长度,IP 地址信息。

DNS 缓存和 hosts 文件

之前 DNS 解析查询过程的图中,共发出了 8 份 DNS 报文,这是非常消耗时间的,所以实际应用上使用 DNS 缓存 :当一个 DNS 服务器接收到一个 DNS 回答后,会将其信息缓存一段时间,当再有一个对相同域名的查询时,便可直接回复。

通过 DNS 缓存,其实很多查询都只需要本地 DNS 服务器便可完成。

我们可以用 dig 命令进行域名查询:

# 查询 www.lanqiao.cn 的 ip 地址,+noedns 是不显示 edns 信息
dig www.lanqiao.cn +noedns

输出解析:

# 这一部分为应答的统计信息
# - QUERY:查询任务个数,这里为 1 个
# - ANSWER:查询到几条 A 记录(IP 地址),这里为 1 条
# - AUTHORITY:几个权威域名服务器,这里为 0 个
# - ADDITIONAL:几个附加信息,这里为 0 个
; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> www.lanqiao.cn +noedns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28554
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0


# 这一部分为问题片段,意思是查询 www.lanqiao.cn 的 A 记录
;; QUESTION SECTION:
;www.shiyanlou.com.        IN    A

# 这一部分为应答片段,意为查询到的 IP 为 115.29.233.149
;; ANSWER SECTION:
www.shiyanlou.com.    43200    IN    A    115.29.233.149

# 这一部分为查询的任务统计信息,比如查询花了多少时间,执行查询的时间等
;; Query time: 8 msec
;; SERVER: 100.100.2.138#53(100.100.2.138)
;; WHEN: Sun Feb 03 17:37:46 CST 2019
;; MSG SIZE  rcvd: 51

FTP

FTP(File Transfer Protocol 文件传输协议)基于 TCP,使用端口号 20(数据)和 21(控制)。

它的主要功能是减少或消除在不同操作系统下处理文件的不兼容性,以达到便捷高效的文件传输效果。

  • FTP 只提供文件传输的基本服务,它采用 客户端—服务器 的方式,一个 FTP 服务器可同时为多个客户端提供服务。
  • 在进行文件传输时,FTP 的客户端和服务器之间会建立两个 TCP 连接:21 号端口建立控制连接,20 号端口建立数据连接
  • FTP 的传输有两种方式:ASCII 传输模式和二进制数据传输模式。

FTP 的工作模式是被动模式(PASV),被动模式中,服务端会创建一个新的随机的非特权端口 P(P> = 1023)与客户端建立数据通道连接。

HTTP

HTTP (HyperText Transfer Protocol 超文本传输协议) 基于 TCP,使用端口号 80 或 8080。

每当你在浏览器里输入一个网址或点击一个链接时,浏览器就通过 HTTP 协议将网页信息从服务器提取再显示出来,这是现在使用频率最大的应用层协议。

这个原理很简单:

  • 点击一个链接后,浏览器向服务器发起 TCP 连接;
  • 连接建立后浏览器发送 HTTP 请求报文,然后服务器回复响应报文;
  • 浏览器将收到的响应报文内容显示在网页上;
  • 报文收发结束,关闭 TCP 连接。

HTTP 报文会被传输层封装为 TCP 报文段,然后再被 IP 层封装为 IP 数据报。

HTTP 请求报文结构:

1549007903327

HTTP 响应报文结构:

1549007953944

可见报文分为 3 部分:

  • 开始行:用于区分是请求报文还是响应报文,请求报文中开始行叫做请求行,而响应报文中,开始行叫做状态行。在开始行的三个字段之间都用空格分开,结尾处 CRLF 表示回车和换行。
  • 首部行:用于说明浏览器、服务器或报文主体的一些信息。
  • 实体主体:请求报文中通常不用实体主体。

请求报文的方法字段是对所请求对象进行的操作,而响应报文的状态码是一个 3 位数字,分为 5 类 33 种:

  • 1xx:通知信息,如收到或正在处理。
  • 2xx:成功接收。
  • 3xx:重定向。
  • 4xx:客户的差错,如 404 表示网页未找到。
  • 5xx:服务器的差错,如常见的 502 Bad Gateway。

Telnet

Telnet和SSH是两种不同的协议,它们都用于远程访问计算机系统,但它们有以下不同之处:

  1. 安全性:Telnet传输数据时不加密,而SSH使用加密技术确保数据的机密性和完整性。这意味着在使用Telnet进行远程访问时,所有传输的数据都是明文的,可能会被黑客截获并窃取,而使用SSH则可以保证数据的安全传输。
  2. 端口号:Telnet使用23号端口,而SSH使用22号端口。这意味着如果你想使用SSH进行远程访问,你需要确保你的计算机防火墙允许22号端口的流量通过,否则你将无法建立连接。
  3. 功能:SSH比Telnet更强大,支持更多的功能,例如文件传输和端口转发等。这使得SSH成为更常见和受欢迎的远程访问协议。

综上所述,SSH比Telnet更加安全和功能更强大,因此在进行远程访问时,SSH更受欢迎。

Telnet 简介

Telnet 协议是 TCP/IP 协议族中的一员,是 Internet 远程登录服务的标准协议和主要方式,它基于 TCP 协议,使用端口 23

终端使用者在本地电脑上使用 telnet 程序,用它连接到服务器,终端使用者可以在 telnet 程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。

Telnet 工作过程

使用 Telnet 协议进行远程登录时必须满足以下条件:

  • 在本地计算机上必须装有包含 Telnet 协议的客户程序;
  • 必须知道远程主机的 IP 地址或域名;
  • 必须知道登录标识与口令。

Telnet 远程登录服务分为以下 4 个过程:

  • 本地与远程主机建立连接。该过程实际上是建立一个 TCP 连接,用户必须知道远程主机的 IP 地址或域名;
  • 将本地终端上输入的用户名和口令及以后输入的任何命令或字符以 NVT ( Net Virtual Terminal ) 格式传送到远程主机。该过程实际上是从本地主机向远程主机发送一个 IP 数据包;
  • 将远程主机输出的 NVT 格式的数据转化为本地所接受的格式送回本地终端,包括输入命令回显和命令执行结果;
  • 最后,本地终端对远程主机进行撤消连接。该过程是撤销一个 TCP 连接。
Telnet 连接远程主机

telnet 使用语法:telnet IP 端口(可选)

Telnet 测试主机端口

telnet 可以测试目标机器的 TCP 端口是否开放。

例如 telnet IP地址 3389 是用来测试目标机器的 3389 端口是否开放,如果连接失败,可能是以下原因:

  • 防火墙屏蔽
  • 目标机器没有启用相关远程桌面服务(windows)
  • 修改了默认占用 3389 端口。

使用 telnet 127.0.0.1 端口 测试本地环境端口开放性,同样也可以使用netstat -pantu 验证。

SMTP 协议和 POP3 协议

SMTP 简介

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式,它使用 TCP 协议,使用端口 25

SMTP 存在两个端:

  • 在发信人的邮件服务器上执行的客户端;
  • 在收信人的邮件服务器上执行的服务器端。

SMTP 的客户端和服务器端同时运行在每个邮件服务器上。当一个邮件服务器在向其它邮件服务器发送邮件消息时,它是作为 SMTP 客户在运行。

SMTP 的连接和发送过程
  • 建立 TCP 连接
  • 客户端向服务器发送 HELO 命令以标识发件人自己的身份,然后客户端发送 MAIL 命令
  • 服务器端以 OK 作为响应,表示准备接收
  • 客户端发送 RCPT 命令
  • 服务器端表示是否愿意为收件人接收邮件
  • 协商结束,发送邮件,用命令 DATA 发送输入内容
  • 结束此次发送,用 QUIT 命令退出

SMTP 协议详解及工作过程

POP3 简介

POP3(Post Office Protocol Version 3 )即邮局协议版本 3,是 TCP/IP 协议族中的一员 ,主要用于支持使用客户端远程管理在服务器上的电子邮件,使用 TCP 协议,使用端口 110

POP3 邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的 POP3 协议。

POP3 工作过程
  • 用户运行用户代理(如 Foxmail, Outlook Express)
  • 用户代理(以下简称客户端)与邮件服务器(以下简称服务器端)的 110 端口建立 TCP 连接
  • 客户端向服务器端发出各种命令,来请求各种服务(如查询邮箱信息,下载某封邮件等)
  • 服务端解析用户的命令,做出相应动作并返回给客户端一个响应
  • 上述的两个步骤交替进行,直到接收完所有邮件转到下一步,或两者的连接被意外中断而直接退出
  • 用户代理解析从服务器端获得的邮件,以适当地形式(如可读)的形式呈现给用户

(参考邮件服务器之 POP3 协议分析

POP3 和 SMTP 协同工作

一封邮件的发送过程:

图片描述

  1. 通过 smtp 协议连接到 smtp 服务器,然后发一封邮件给 sohu 的 smtp 服务器;
  2. 通过 smtp 协议将邮件转投给 sina 的 smtp 服务器(邮件发送服务器);
  3. 将接收到的邮件存储到 gacl@sina.com这个邮件账号分配的存储空间中;
  4. 通过 POP3 协议连接到 POP3 服务器收取邮件;
  5. gacl@sina.com 账号的存储空间当中取出邮件;
  6. POP3 服务器将取出来的邮件回送给 gacl@sina.com 账户。