搜公众号
推荐 原创 视频 Java开发 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库
Lambda在线 > 小情绪网络 > 第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

小情绪网络 2018-12-12
举报

TCP/UDP协议

这种传输协议主要工作在传输层,传输方式分为

tcp(面向连接的可靠传输,流量控制,延迟高)

udp(不可靠传输,不建立连接,能精尽最大能力传输数据,但是不保证数据的完整性,延迟低)

第二季_06_网络基础_TCP/UDP协议

我们主要讲解tcp的传输原理,先看看tcp的传输特点

第二季_06_网络基础_TCP/UDP协议

看看tcp的数据包里面有什么

第二季_06_网络基础_TCP/UDP协议

看看皇家翻译版本

第二季_06_网络基础_TCP/UDP协议

1. 源端口和目的端口

2. 序号

占4字节,是TCP段所发送的数据部分第一个字节的序号。在TCP传送的数据流中,每一个字节都有一个序号。建立连接时,发送方将初始序号(Initial Sequence Number, ISN)填写到第一个发送的TCP段序号中。

3. 确认号

占4字节,是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个TCP段的首部中的序号,等于已经成功收到的TCP段的最后一个字节序号加1。确认号在ACK标志为1时有意义,除了主动发起连接的第一个TCP段不设置ACK标志外,其后发送的TCP段都会设置ACK标志。

4. 数据偏移

占4比特,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。数据偏移以32位为长度单位,因此TCP首部的最大长度是60(15*4)个字节

5. 控制位

一共6个,占6比特,设置为1时有效。按顺序依次为:URG、ACK、PSH、RST、SYN、FIN。

URG

紧急位,为1时,首部中的紧急指针有效

ACK

确认位,为1时,首部中的确认号有效

PSH

推位,为1时,要求把数据尽快交给应用程序

RST

复位标志,为1时,复位连接,一般在出错或关闭连接时使用

SYN

同步位,在建立连接时使用,当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,在发回的报文段中使SYN=1和ACK=1

FIN

结束位,为1时,表示发送方完成了数据发送


6. 窗口

占2字节,表示报文段发送方期望接收的字节数,可接收的序号范围是从接收方的确认号开始到确认号加上窗口大小之间的数据。

7. 校验和

校验和包含了伪首部、TCP首部和数据,校验和是TCP强制要求的,由发送方计算,接收方验证。

8. 紧急指针

URG标志为1时,紧急指针有效,表示数据需要优先处理。紧急指针指出在TCP段中的紧急数据的最后一个字节的序号,使接收方可以知道紧急数据共有多长。

9. 选项

最常用的选项是最大段大小(Maximum Segment Size,MSS),向对方通知本机可以接收的最大TCP段长度。MSS选项只在建立连接的请求中发送。

看看常见协议基于tcp/udp的端口号

第二季_06_网络基础_TCP/UDP协议

看看tcp的3次握手建立连接的原理

第二季_06_网络基础_TCP/UDP协议

简单说一下


列举的a与b均为随机数

① 

A 的 TCP 向 B 发出连接请求报文段,其首部中的同步比特 SYN 应置为1,并选择序号 a,表明传送数据时的第一个数据字节的序号是 a(设置初始段序号SEQ = a ,例如seq = 26 500)。

 B 的 TCP 收到连接请求报文段后,如同意,则发回确认。
B 在确认报文段中应将 SYN 置为 1,其确认号ACK应为 a + 1(ACK 26 501),同时也给出自己的选择序号 y(设置初始段序号seq = b,例如seq= 29 010)。

 A 收到此报文段后,向 B 给出确认,其确认号应为 b + 1(ACK = 29011)。
A 的 TCP 通知上层应用进程,连接已经建立。
当运行服务器进程的主机 B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程,连接已经建立。

由于客户对报文段进行了编号,它知道哪些序号是期待的,哪些序号是过时的。当客户发现报文段的序号是一个过时的序号时,就会拒绝该报文段,这样就不会造成重复连接。


当它们将数据传输完成时,双方就会释放连接


TCP四次挥手

  由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。原则是主动关闭的一方发送一个FIN报文来表示终止这个方向的连接,收到一个FIN意味着这个方向不再有数据流动,但是另一个方向仍能发送数据,直到另一个方向也发送FIN报文。TCP连接释放的过程如下图所示:

第二季_06_网络基础_TCP/UDP协议

以下是释放连接的四次挥手过程:


  1. 主机A进程主动向主机B发出连接释放请求报文,并停止发送数据,主动关闭TCP连接。释放连接报文段中控制为FIN=1,序列号为seq=p,发送该报文段后客户端进入FIN_WAIT_1(终止等待1)状态,等待主机B确认。这是TCP连接释放的第一次挥手。

  2. 主机A收到连接释放请求报文段后即发出确认释放连接的报文段,该报文段中控制位ACK=1,确认号为ack=p+1,然后主机B进入CLOSE_WAIT(关闭等待)状态。此时TCP处于半关闭状态,即主机A已经不向主机B发送数据,但主机B仍可向主机A发送数据。这是TCP连接释放的第二次挥手。

  3. 主机A收到主机B的确认信息后,就进入了FIN_WAIT_2(终止等待2)状态,等待主机B发出连接释放请求报文段,若没有数据需要传输,主机B被动向主机A发出链接释放请求报文段,报文段中控制位FIN=1,序列号seq=q,此时服务器进入LAST_ACK(最后确认)状态,等待主机A的确认应答,这是TCP连接释放的第三次挥手。

  4. 主机A收到主机B的连接释放请求后,必须对此发出确认。确认报文段中控制位ACK=1,确认应答号ack=q+1,主机A发出确认应答消息后进入TIME_WAIT(时间等待)状态。在这段时间内TCP连接并没有释放,必须等待2MSL时间后,客户端才进入CLOSED状态。主机B收到客户端的确认应答后,就进入CLOSED状态。直到主机A和主机B都进入了CLOSED状态后,连接就完全释放了,这是TCP连接释放的第四此挥手。


TCP相关疑问

为什么在TCP协议里,建立连接是三次握手,而关闭连接却是四次挥手?
  因为当处于LISTEN状态的服务器端收到来自客户端的SYN报文(客户端希望新建一个TCP连接)时,它可以把ACK(确认应答)和SYN(同步序号)放在同一个报文里来发送给客户端。但在关闭TCP连接时,当收到对方的FIN报文时,对方仅仅表示对方已经没有数据发送给你了,但是你自己可能还有数据需要发送给对方,则等你发送完剩余的数据给对方之后,再发送FIN报文给对方来表示你数据已经发送完毕,并请求关闭连接,所以通常情况下,这里的ACK报文和FIN报文都是分开发送的。

为什么一定要进行三次握手?
  当客户端向服务器端发送一个连接请求时,由于某种原因长时间驻留在网络节点中,无法达到服务器端,由于TCP的超时重传机制,当客户端在特定的时间内没有收到服务器端的确认应答信息,则会重新向服务器端发送连接请求,且该连接请求得到服务器端的响应并正常建立连接,进而传输数据,当数据传输完毕,并释放了此次TCP连接。若此时第一次发送的连接请求报文段延迟了一段时间后,到达了服务器端,本来这是一个早已失效的报文段,但是服务器端收到该连接请求后误以为客户端又发出了一次新的连接请求,于是服务器端向客户端发出确认应答报文段,并同意建立连接。如果没有采用三次握手建立连接,由于服务器端发送了确认应答信息,则表示新的连接已成功建立,但是客户端此时并没有向服务器端发出任何连接请求,因此客户端忽略服务器端的确认应答报文,更不会向服务器端传输数据。而服务器端却认为新的连接已经建立了,并在一直等待客户端发送数据,这样服务器端一直处于等待接收数据,直到超出计数器的设定值,则认为服务器端出现异常,并且关闭这个连接。在这个等待的过程中,浪费服务器的资源。如果采用三次握手,客户端就不会向服务器发出确认应答消息,服务器端由于没有收到客户端的确认应答信息,从而判定客户端并没有请求建立连接,从而不建立该连接。

为什么TIME_WAIT状态必须等待2MSL时间,而不直接给进入CLOSED状态?
  主要有两个原因:
  
  

  1. TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到ACK,就会出发被动端重发FIN。因为最后一次确认应答ACK报文段很有可能丢失,因而使被动关闭方处在LAST_ACK,此时被动关闭方会重复这个FIN+ACK报文段,在这等待的2MSL时间被主动关闭方重新收到这个被动关闭方重发的FIN+ACK报文段,因此,主动关闭方会重新发送确认应答信息,从而重新启动2MSL计时器,直到通信双方都进入CLOSED状态。如果主动关闭方在TIME_WAIT状态不等待一段时间就直接释放连接并进入CLOSED状态,那么主动关闭方无法收到来自被动关闭方重发的FIN+ACK报文段,也就不会再发送一次确认ACK报文段,因此被动关闭方就无法正常地进入CLOSED状态。

  2. 有足够的时间让这个连接不会跟后面的连接混在一起。防止已失效的请求连接出现在本连接中。在连接处于2MSL等待时,任何迟到的报文段将被丢弃,因为处于2MSL等待的,由该插口(插口是IP端口对的意思,socket)定义的连接在这段时间内将不能被再用,这样就可以使下一个新的连接中不会出现这种旧的连接以前延迟的报文段。


是不是这样我们需要使用抓包工具Wireshark分析下才能证明这个原理的结论

第二季_06_网络基础_TCP/UDP协议

我过滤下抓包的数据,因为我们要看的是tcp,所以直接搜索tcp就行了

第二季_06_网络基础_TCP/UDP协议

天呐,那么多包,我怎么知道我连接的百度的过程,还记得上节课讲的dns吗,我们抓包工具抓出来的都是ip,那么我们用nslookup查一下www.baidu.com的ip是多少

第二季_06_网络基础_TCP/UDP协议

那么在抓包工具中仔细找找对应的ip

第二季_06_网络基础_TCP/UDP协议

往下翻就找到了这个百度的IP

我们找到第一个百度的ip

第二季_06_网络基础_TCP/UDP协议

来分析下数据包

第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

来看看下一个数据包

第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

来仔细看看

第二季_06_网络基础_TCP/UDP协议

回包还有一个另外的seq等于0

看看下一个包

第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

总结一下这次访问百度的3次握手的过程就是

第一次握手,我访问了百度,代表我请求和百度建立连接,发送了一个SYN(seq=0)

第二次握手,百度收到请求包后,给我回包,也向我请求建立连接,SYN(seq=0新生成随机数 ack=1代表同意建立连接)

第三次握手,我收到百度的包之后,我回复百度SYN(seq=1 ack=1)此时双方建立连接,然后就是通过https协议传输网页数据了,参考上图过程。

四次挥手实验

第二季_06_网络基础_TCP/UDP协议


找到最后的四次挥手的过程数据包

第一次挥手


第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

第二次挥手

第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

第三次挥手


第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议

第四次挥手

第二季_06_网络基础_TCP/UDP协议

第二季_06_网络基础_TCP/UDP协议


总结先就是


版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《第二季_06_网络基础_TCP/UDP协议》的版权归原作者「小情绪网络」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注小情绪网络微信公众号

小情绪网络微信公众号:xiaoqingxu520520520

小情绪网络

手机扫描上方二维码即可关注小情绪网络微信公众号

小情绪网络最新文章

精品公众号随机推荐

举报