TCP详解
TCP和UDP
TCP和UDP都是传输层的协议。
UDP:用户数据报协议,面向无连接,可以单播、多播、广播,面向数据报,不可靠交付
TCP:传输控制协议,面向连接的,可靠的,基于字节流,仅支持单播传输
TCP三次握手
TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓“连接”,其实是客户端和服务器端内存里保持的一份关于对方的信息(IP地址、端口号)
TCP可以看作是一种字节流,他会处理IP层或以下的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放到TCP头部
TCP提供一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接、四次挥手来关闭一个连接。
第一次握手: 1.客户端将SYN标志位置为1 2.生成一个随机的32位的序号seq=J ,这个序号后边是可以携带数据(数据的大小) 第二次握手: 1.服务器端接收客户端的连接:ACK=1 2.服务器会回发一个确认序号: ack=客户端的序号+数据长度(上图中假设传输数据为0,仅SYN占据了一个字节)+SYN/FIN(按一个字节算) 3.服务器端会向客户端发起连接请求: SYN=1。4.服务器会生成一个随机序号:seq =K 第三次握手:1.客户单应答服务器的连接请求:ACK=1。2.客户端回复收到了服务器端的数据:ack=服务端的序号+数据长度+SYN/FIN(按一个字节算)
seq为序号,ack为确认序号。仅当SYN=1的时候,序号seq才有用。同理,仅当ACK=1的时候,确认序号ack才有用。
为什么是3次握手呢?
通过3次握手才能够确定客户端的发送数据、数据数据的功能正常。服务器端的接收数据和发送数据正常。2次握手显然无法证明,比如客户端端发送SYN连接请求,服务器端回应ACK报文并发送,那么只能证明客户端发送数据正常,接收数据的能力不能确定。4次握手也可以达到,但是3次就能搞定,多花费一次没有必要。并且在三次握手的过程中,双方协商了一些信息,例如双方发送序号的初始值、最大段尺寸。
TCP滑动窗口
滑动窗口是一种流量控制技术。早期的网络通信中,通信双方不会考虑网络拥挤情况直接发送数据。由于大家不知道网络拥挤状况,同时发送数据,导致中间节点阻塞丢包,谁也发送不了数据,所以就有了滑动窗口机制来解决此问题。滑动窗口协议是用来改善吞吐量的一种技术,即容许发送方在接收任何应答之前传送附加的包。接收方告诉发送方在某一时刻能送多少包(窗口尺寸)。
还有一种情况,当发送端发送的速度较快,接收端收到数据后处理速度较慢,而接收缓冲区的大小是固定的(一般采用循环队列),就会丢失数据。TCP协议通过“滑动窗口”机制解决着一问题。
看上面的通讯过程:
- 发送端(客户端)发起连接,声明最大尺寸是1460。初始序号是0,窗口大小4K,表示“我的接收缓冲区还有4K字节空闲区,你发送的数据不要超过4K”。接受端应答连接请求,声明最大段尺寸是1024,初始序号是8000,窗口大小是6K。发送端应答,三次握手结束。
- 发送端发出段4-9,每一个段带1K的数据,发送端根据窗口大小知道接受端的缓冲区满了,因此停止发送数据。(6*1024=6K)
- 接收端的应用程序处理了2K数据,接受缓冲区有2K空闲,接收发出段10,再应答已收到6K数据同时声明窗口大小为2K,并且包含了下一次发送的序号
- 接收端的应用程序处理了2K数据,接收缓冲区有4K空闲,接收发出段11。重新声明窗口大小为4K.
- 发送端发出段12-13,每一个段带1K数据,段13同时包含FIN位(FIN表示断开连接)
- 接收端应答接收到2K数据(6145-8192),再加上FIN位占用一个序号8193,因此告知发送端下次发送从序号8194开始,连接处于半关闭状态,接收段同时声明窗口大小为2K
- 接收端的应用程序处理了2K数据,接收端重新声明窗口大小为4K
- 接收端的应用程序处理了2K数据,接收端重新声明窗口大小为6K
- 接收端的应用程序处理全部数据后,决定关闭连接,发出段17,包含FIN位,发送端应答,连接完全关闭随着应用程序提走数据,虚线框不断向右滑动,因此称为滑动窗口
我们还可以分析出一个现象:应用程序所看到的数据是一个整体或者说是一个流,在底层通讯中这些数据可能被拆成数据包来发送,但是一个数据包有多少字节对应用程序是不可见的,因此TCP协议是面向字节流的协议,而UDP是面向消息的协议,每一个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的
标签:接收端,TCP,基础知识,发送,序号,数据,连接 From: https://blog.51cto.com/u_16188116/6861720