关于TCP/IP
一、网络模型
计算机网络的两种模型:OSI 模型和 TCP/IP 模型
由于 OSI 模型过于复杂难以实现,导致 TCP/IP 模型更早地应用在现实中,这也使得 TCP/IP 模型成为标准
在 OSI 模型中,将计算机网络分成了 7 层,而在 TCP/IP 模型中则分成了 4 层,其各层对应关系如下表所示:
OSI | TCP/IP | 对应网络协议 | 所在位置 |
应用层 | 应用层 | TFTP, FTP, NFS, WAIS | 主机 |
表示层 | Telnet, Rlogin, SNMP, Gopher | ||
会话层 | SMTP, DNS | ||
传输层 | 传输层 | TCP, UDP | |
网络层 | 网际层 | IP, ICMP, ARP, RARP, AKP, UUCP | 媒介 |
数据链路层 | 网络接口层 | FDDI, Ethernet, Arpanet, PDN, SLIP, PPP | |
物理层 | IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
> 网卡的实现
物理层与数据链路层的功能
> HTTP 与 HTTPS
在 Internet 中所有的传输都是通过 TCP/IP 进行的。
HTTP 协议作为 TCP/IP 模型中应用层的协议也不例外,HTTP 协议通常承载于 TCP 协议之上,有时也承载于 TLS 或 SSL 协议层之上,这个时候,就成了我们常说的 HTTPS
HTTP 默认的端口号为 80,HTTPS 的端口号为 443
二、UDP与TCP协议
在整个计算机网络体系中,最核心的当属是位于传输层的 TCP 与 UDP 协议了。因为他们位于主机协议栈的最底层,向上方应用层提供不同的数据交付方式。
1、UDP 协议
> 什么是 UDP 协议:
UDP 全称用户数据报协议(User Datagram Protocal),它有以下几个值得注意的特点:
-
UDP 不能保证可靠传输,也就更不能保证所发送的数据的到达顺序,它所实现的是尽最大的努力交付。
-
UDP 是面向数据报文的、无连接的协议,因此它的开销低并且发送器前的时延小(因为不用建立连接啊),面向报文也使得 IP 层在传输 UDP 协议的报文时既不会拆分也不会合并。
-
UDP 可以支持一对一、一对多、多对一、多对多的通信。
-
UDP 没有拥塞控制功能,它的发送速率不会随着网络出现的拥塞而降低,所以它的实时性较好。这也是许多视频聊天应用采用它的原因。
> UDP 报文头部格式:
其中从 1 到 8 字节分别是来源端口号、目的端口号、报文长度、检验和,每个字段各占两字节。
UDP 的通信方式较为简单,发送端发送完一个报文继续发送下一个,待将所有报文发送完毕通信就结束了。
接收方也是如此。
2、TCP 协议
> 什么是 TCP 协议:
TCP 全称传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP 协议所要实现的功能是端到端之间的可靠传输,因此,相较于 UDP 协议而言,TCP 协议要复杂的多。
相对于 UDP 协议,TCP 协议有下面的几个特点:
-
TCP 协议保证可靠传输,也就是说发送的数据是什么样,接收的数据也是什么样。
-
TCP 协议是有连接的、面向数据流的协议。有连接是说数据传送前通信双方需要建立连接、通信完毕后需要断开连接,不过这里所提到的连接都是逻辑上的连接。面向数据流的意思是说发送方应用程序发送的数据是什么顺序,接收方应用读取的接收到的数据也是什么顺序。
-
TCP 协议提供的是端到端的通信,也就是说一条TCP连接只能提供一对一的通信。不过,一个应用可以同时建立多条 TCP 连接来实现与多个目标的通信。
-
TCP 协议提供拥塞控制功能,会在网络状况良好的情况下适当提高发送/接收速率,反之则适当降低发送/接收速率。这样,将会提高对网络的利用率。
此外,还需要注意的是,TCP 提供的是全双工的通信。
> TCP 数据封包的结构示意:
各个字段功能如下:
来源端口(2字节):标识来源端口号
目的端口(2字节):标识目的端口号
序列号码(4字节):表明此封包在字节流中的顺序号(因为 TCP 是面向字节流的协议,需要保证最终的数据顺序与发送方发送的顺序一致,所以需要这个字段来表明该封包在字节流中的位置)
确认号码(4字节):对此前按顺序收到的最后一个封包的序列号码的确认(确认号 =n,表示 n-1 及其之前的封包都已经收到)
报头长度(1字节):指示报文头部的长度
保留字段(10位):暂时没打算好干啥用,一律置 0
标识符(6位):
- URG—为 1 表示高优先级数据包,紧急指针字段有效
- ACK—为 1 表示确认号字段有效。TCP 规定连接建立后,所有传送的报文段都必须把该字段置为 1
- PSH—为 1 表示是带有PUSH标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满
- RST—为 1 表示出现严重差错。可能需要重现创建 TCP 连接。还可以用于拒绝非法的报文段和拒绝连接请求
- SYN—为 1 表示这是连接请求或是连接接受请求,用于创建连接和使顺序号同步
- FIN—为 1 表示发送方没有数据要传输了,要求释放连接
窗口(2字节):表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小。用于流量控制
校验和(2字节)对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。这是一个强制性的字段
紧急指针(2字节):本报文段中的紧急数据的最后一个字节的序号
选项字段(最多40字节):每个选项的开始是 1 字节的 kind 字段,说明选项的类型
> 超时重传
为了搞明白下面要说的 TCP 的一些机制,首先需要知道 TCP 协议能够实现可靠传输的一个基本的原理--超时重传。
说来很简单,其实就是收到当接收方收到一个数据封包的时候就向发送方发送一个确认数据封包。而当发送方发送完一个数据封包经过一段时间没有收到接收方的确认封包时,就会将上一个封包再次向接收方发送一次。
当然,TCP 中真正的机制比这个要复杂的多,但是基于的原理都是一样的。
> TCP 三次握手
在说 TCP 连接之前先插播一个小故事。
有一天,小明到店里去买笔,于是跟老板有了以下对话:
小明:我要一支笔。
老板:你确定要一支笔?
小明:我确定要一支笔!
于是老板就给了小明一支笔……
这就是典型的 TCP 连接建立的过程。如下面的图:
ACK 表示 TCP 包头中的确认标识
-
(我要一支笔。)客户端向服务器发送建立连接请求数据包,其中包头内容 SYN=1,seq=x(自己随机选的起始序号)
-
(你确定要一支笔?)服务器收到请求后,如果同意建立连接,就向客户端发送同意建立连接请求数据封包,其包头内容 SYN=1,ACK=1,ack=x+1 (seq=y(同样也是自己随机挑选的)
-
(我确定要一支笔!)客户端收到服务器发来的确认请求后,也向服务器发送确认封包,其内容 ACK=1,ack=y+1(原理同上),seq=x+1(毕竟已经发送过 seq=x 的封包了),随后客户端就进入连接建立状态,而服务器就在收到这个确认封包后也进入连接建立状态
以上步骤就是俗称的“TCP 三次握手”
> TCP 四次挥手
当然,有连接建立,就有连接释放,客户端与服务器之间的连接释放过程大概是下面这个样子的
跟建立连接的时候差不多,大概过程大概向下面这样:
-
客户端向服务器发送连接请求释放封包,封包内容为 FIN=1,seq=u
-
服务器收到后,决定要跟客户端释放连接,可是还有数据没传送完啊,就先发一个封包告诉客户端我可以释放连接,你可以不用向我发送数据了,可是我还有数据没有传送完,所以在我告诉你结束之前你得一直接收我的数据(别忘了,TCP 可是全双工的)。所以所发送封包内容为:ACK=1,ack=u+1,seq=v(FIN=0表示我还有数据要发送)
-
服务器发送完数据后,告诉客户端我都发送完了,可以结束了。于是发送封包为 FIN=1,ACK=1,ack=u+1,seq=w(中间还传输过数据,所以可能不是 v+1)
-
客户端收到服务器的确认后,再次向服务器发送确认,内容是 ACK=1,ack=w+1,seq=u+1
-
发送完上面的确认封包后,客户端再等一段时间(2MSL)后,就断开连接。至此,连接正常释放
如上步骤就是俗称的“TCP 4次挥手”。
这里之所以是 4 次,主要是与建立连接时相比,服务器的确认和结束被分成了两个封包分别发送了出去
三、总结
1、传输层提供端到端的可靠报文传递和错误恢复
2、网卡实现的是物理层与数据链路层的功能
3、HTTP 的端口号是 80;HTTPS 的端口号是 443
4、UDP 注重数据传输快,TCP 注重数据可靠性
5、域名系统 DNS 采用的是 UDP,而非 TCP