首页 > 代码库 > 读书笔记:计算机网路6章:传输层
读书笔记:计算机网路6章:传输层
这是我在Coursera上的学习笔记。课程名称为《Computer Networks》,出自University of Washington。
由于计算机网络才诞生不久,目前正在以高速在发展,所以有些旧的教材可能都已经跟不上时代了。这门课程在2013年左右录制,知识相对还是比较新的。覆盖了计算机网络中的各个协议层,从物理层到应用层都讲得非常仔细。学完这门课程之后对计算机网络会有比较深刻的了解。
传输层概述
课程位置
我们已经到达传输层了
传输层基于网络层
回忆
传输层是端到端的通信,中间的路由过程不会改变传输层的数据
应用数据包含在TCP包中,TCP包包含在IP包中,IP包包含在帧中
传输层提供的服务
提供框中不同的数据传输方式:UDP TCP
UDP和TCP的比较
TCP拥有全部特性,UDP只是名义上的传输层。
TCP所有的字节只传输一次,按顺序。UDP消息可能会乱序,重复,丢失
TCP支持任意长度的内容。UDP只能支持有限长度的内容
TCP发送者和接受者能同步流的控制。UDP无视网络状态,可以任意发送
TCP可以控制阻塞。UDP无视网络状态,可以任意发送
SOCKET API
简单的网络抽象接口
支持UDP和TCP
SOCKET允许不同的应用使用不同的端口
UDP和TCP的接口是一样的。除了LISTEN ACCEPT CONNECT是TCP特有的接口,其他接口都是一样的。
端口
应用程序之间通过IP地址、协议、端口来区分不同的应用
服务器通常将端口绑定到公认的端口上(端口号<1024)
客户端通常使用临时端口
公认端口
20 21 FTP
22 SSH
25 SMTP
80 HTTP
110 POP3
143 IMAP
443 HTTPS
543 RTSP 多媒体控制
631 IPP 打印机共享
话题
UDP TCP 连接 滑动窗口 流控制 重发计时器
UDP
话题
用UDP发送消息
UDP
在不需要可靠连接的情况下使用UDP
比如VoIP DNS RPC DHCP
数据报SOCKET
客户端,服务端都调用SOCKET
服务端调用BIND
服务端调用RECV FROM(阻塞)
客户端调用SENDTO
客户端调用RECVFROM(阻塞)
服务端调用SENDTO
客户端和服务端都调用CLOSE
UDP缓冲
操作系统接收到数据包时会将数据包保存到内存中,当应用调用RECVFROM时,操作系统会将内存中的数据包传递给应用。这样,应用处理一个数据包时,即使收到数据报也不会丢包
UDP包头
使用端口来区分不同的应用
UDP最长长度为64K
有16位CHECKSUM
具体格式:Source Port | Dest Port | UDP Length | UDP Checksum
checksum是可选的,如果是0表示没有校验。(IPv6不可选)
checksum覆盖IP地址字段
UDP check sum计算过程
IPv4 Pseudo Header[edit]
When UDP runs over IPv4, the checksum is computed using a "pseudo header"[9] that contains some of the same information from the real IPv4 header. The pseudo header is not the real IPv4 header used to send an IP packet, it is used only for the checksum calculation.
Offsets | Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Octet | Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
0 | 0 | Source IPv4 Address | |||||||||||||||||||||||||||||||
4 | 32 | Destination IPv4 Address | |||||||||||||||||||||||||||||||
8 | 64 | Zeroes | Protocol | UDP Length | |||||||||||||||||||||||||||||
12 | 96 | Source Port | Destination Port | ||||||||||||||||||||||||||||||
16 | 128 | Length | Checksum |
The source and destination addresses are those in the IPv4 header. The protocol is that for UDP (see List of IP protocol numbers): 17 (0x11). The UDP length field is the length of the UDP header and data.
UDP checksum computation is optional for IPv4. If a checksum is not used it should be set to the value zero.
当UDP运行于IPv4时,checksum通过虚拟报头进行计算。虚拟报头中包括了IPv4中的一些字段。虚拟报头不会在数据的传输过程中出现,它只是用来计算checksum。
Source Addr和Dest Addr来自IPv4。UDP protocol为UDP协议号17。UDP length是原来UDP报头中的字段。
UDP checksum在IPv4中是可选的。如果checksum没有用到,那么它应该设为0。
建立连接
话题
如何建立连接
建立链接
在通信前,发送方和接收方都需要向对方建立连接。
三次握手
客户端生成随机的ISN初始序列号,并向服务端发送SYN(x)
服务端回应客户的请求,生成一个随机的ISN,并向客户端发送SYN(y)ACK(x+1)
客户端回应ACK(y+1)
SYN如果中途丢失,会重新发送
序列号和ACK号会在后续的数据包中用到
即使SYN或ACK延迟、重复,TCP也能提供可靠的连接
TCP连接有限状态机
见图
状态:CLOSED LISTEN SYN_SENT SYN_RECV ESTABLISHED
有限状态机是一种帮助考虑所有情况的有利工具
TCP允许一次有多个连接
释放连接
话题
如何释放连接
释放连接
有序地释放连接
关键问题是如何提供可靠的释放机制
TCP通过对称的释放机制,服务端和客户端独立释放连接
步骤
主动方发送FIN(X),被动方发送ACK
被动方发送FIN(Y),主动方发送ACK
FIN如果中途丢失,会重新传输
每对FIN ACK只关闭一个方向的连接
TCP释放有限状态机
ESTABLISHED
FIN_WAIT_1:等待ACK
FIN_WAIT_2:等待对方的FIN
TIME_WAIT:为了提高可靠性,关闭连接之后要等待一段时间
CLOSED
CLOSE_WAIT
LAST_ACK
TIME_WAIT
关闭连接之后等待很长一段时间,通常是分段生命周期的两倍,也就是2分钟。
因为ACK可能会丢失,这样做是为了让关闭连接更可靠
如果不等待,可能后续的连接会影响到本次连接
TCP连接有限状态机
TCP释放有限状态机
滑动窗口
话题
滑动窗口算法
提高可靠性
基于STOP-AND-WAIT
回忆
ARQ协议要求每次发送都需要对方回复ACK,在等待对方回复的时间里,发送方没有数据传输,这样就造成了带宽的浪费
STOP-AND-WAIT的限制
一次只能发送一包消息,会造成带宽的浪费
滑动窗口
是STOP-AND-WAIT算法的升级版
允许一次发送W个数据包
W=2*带宽*延迟/数据包大小
滑动窗口协议
分为两种:GO-BACK-N、SELECTIVE-REPEAT
TCP使用SELECTIVE-REPEAT
发送方
当未确认的包小于W时,发送方可以不停地发送数据,直到未确认的包大于W
GO-BACK-N
接收方只记录最后ACK的帧号LAS。
当另外一个ACK到达时,如果ACK号为LAS+1,那么将LAS增加1,否则就丢包
SELECTIVE-REPEAT
在内存中建立W个缓冲,记录每个包的状态
当ACK到达后更新包的状态
重发
GO-BACK-N使用一个计时器来检测数据包的丢失
SELECTIVE-REPEAT使用W个计时器来检测丢包
序号
序号的范围是多少比较合适呢
序号随时间变化的图
流控制
话题
在滑动窗口算法中增加流控制
防止发送者发送太快
问题
滑动窗口可以充分利用带宽,但是如果接收方无法处理太大量的数据,怎么办呢
接收方
发送方已经接收到数据了,但是没有调用RECV接口。这种情况下数据包的ACK不会发送,服务端也不会发送更多数据
接收方可以直接告诉发送方它能接受的缓冲区大小,WIN=#ACCEPTABLE
流控制
TCP中有WIN字段,就是用来流控制的
例子
发送方发送2K数据,SEQ=0
接收方ACK=2048,WIN=2048
发送方发送2K数据,SEQ=2048
接收方ACK=4096,WIN=0
发送方不发送数据,因为WIN是0,表示对方无法接收数据
接收方ACK=4096,WIN=2048
发送方发送1K数据,SEQ=4096
超时重发
话题
如何设置超时重发
重发
在滑动窗口算法中,检测丢包就是通过超时来实现的
超时问题
多久才算超时呢?
在LAN中很好确定超时时间,因为可以通过RTT(RoundTripTime)来推导,但是在Internet中很难确定超时时间,因为互联网延迟每个地方都不一样,RTT都是有区别的。主要原因在于数据包排队
由于网络延迟会变化,所以需要将超时时间自动适应不同的网络环境
自适应的超时时间
SRTT(n+1) = 0.9*SRTT(n) + 0.1*RTT(n+1)
Svar(n+1) = 0.9*Svar(n) + 0.1*|RTT(n+1)-SRTT(n+1)|
TCP超时时间(n)=SRTT(n)+4*Svar(n)
SRTT = 平滑RTT
这种方法计算简单,对于性能和健壮性来说这种方法很重要
TCP
话题
TCP如何工作
TCP特性
可靠的字节流
基于连接
使用滑动窗口提高可靠性
流控制
通过阻塞控制来分配网络带宽
可靠的字节流
客户端调用四次send函数,接收方可能调用一次recv就把所有的消息都接收完毕。因为TCP是字节流,分界点不依靠send
数据双向传递
TCP头部格式
见表格
TCP滑动窗口 - 接收方
通过递增的ACK告诉发送方,下一个数据包的序号是什么
SELECTIVE ACK让发送方得知接收状态
TCP滑动窗口 - 发送方
使用自适应的超时重发来重新发送数据
根据ACK的状况猜测丢包情况,立即重发数据。这样做可以避免超时重发的发生
TCP头部
SYN/FIN/RST 标志是用于连接的
WINDOW SIZE 是用于流量控制的
其他TCP细节
TCP会有许许多多奇怪的问题,但是这些都属于细节了
最大的问题就是阻塞控制了,下一章将会讲到
Offsets | Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Octet | Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
0 | 0 | Source port | Destination port | ||||||||||||||||||||||||||||||
4 | 32 | Sequence number | |||||||||||||||||||||||||||||||
8 | 64 | Acknowledgment number (if ACK set) | |||||||||||||||||||||||||||||||
12 | 96 | Data offset | Reserved 0 0 0 | N S | C W R | E C E | U R G | A C K | P S H | R S T | S Y N | F I N | Window Size | ||||||||||||||||||||
16 | 128 | Checksum | Urgent pointer (if URG set) | ||||||||||||||||||||||||||||||
20 ... | 160 ... | Options (if data offset > 5. Padded at the end with "0" bytes if necessary.) ... |