第二季_06_网络基础_TCP/UDP协议
Posted 小情绪网络
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二季_06_网络基础_TCP/UDP协议相关的知识,希望对你有一定的参考价值。
TCP/UDP协议
这种传输协议主要工作在传输层,传输方式分为
tcp(面向连接的可靠传输,流量控制,延迟高)
udp(不可靠传输,不建立连接,能精尽最大能力传输数据,但是不保证数据的完整性,延迟低)
我们主要讲解tcp的传输原理,先看看tcp的传输特点
看看tcp的数据包里面有什么
看看皇家翻译版本
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的端口号
看看tcp的3次握手建立连接的原理
简单说一下
列举的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连接释放的过程如下图所示:
以下是释放连接的四次挥手过程:
主机A进程主动向主机B发出连接释放请求报文,并停止发送数据,主动关闭TCP连接。释放连接报文段中控制为FIN=1,序列号为seq=p,发送该报文段后客户端进入FIN_WAIT_1(终止等待1)状态,等待主机B确认。这是TCP连接释放的第一次挥手。
主机A收到连接释放请求报文段后即发出确认释放连接的报文段,该报文段中控制位ACK=1,确认号为ack=p+1,然后主机B进入CLOSE_WAIT(关闭等待)状态。此时TCP处于半关闭状态,即主机A已经不向主机B发送数据,但主机B仍可向主机A发送数据。这是TCP连接释放的第二次挥手。
主机A收到主机B的确认信息后,就进入了FIN_WAIT_2(终止等待2)状态,等待主机B发出连接释放请求报文段,若没有数据需要传输,主机B被动向主机A发出链接释放请求报文段,报文段中控制位FIN=1,序列号seq=q,此时服务器进入LAST_ACK(最后确认)状态,等待主机A的确认应答,这是TCP连接释放的第三次挥手。
主机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状态?
主要有两个原因:
TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到ACK,就会出发被动端重发FIN。因为最后一次确认应答ACK报文段很有可能丢失,因而使被动关闭方处在LAST_ACK,此时被动关闭方会重复这个FIN+ACK报文段,在这等待的2MSL时间被主动关闭方重新收到这个被动关闭方重发的FIN+ACK报文段,因此,主动关闭方会重新发送确认应答信息,从而重新启动2MSL计时器,直到通信双方都进入CLOSED状态。如果主动关闭方在TIME_WAIT状态不等待一段时间就直接释放连接并进入CLOSED状态,那么主动关闭方无法收到来自被动关闭方重发的FIN+ACK报文段,也就不会再发送一次确认ACK报文段,因此被动关闭方就无法正常地进入CLOSED状态。
有足够的时间让这个连接不会跟后面的连接混在一起。防止已失效的请求连接出现在本连接中。在连接处于2MSL等待时,任何迟到的报文段将被丢弃,因为处于2MSL等待的,由该插口(插口是IP端口对的意思,socket)定义的连接在这段时间内将不能被再用,这样就可以使下一个新的连接中不会出现这种旧的连接以前延迟的报文段。
是不是这样我们需要使用抓包工具Wireshark分析下才能证明这个原理的结论
我过滤下抓包的数据,因为我们要看的是tcp,所以直接搜索tcp就行了
天呐,那么多包,我怎么知道我连接的百度的过程,还记得上节课讲的dns吗,我们抓包工具抓出来的都是ip,那么我们用nslookup查一下www.baidu.com的ip是多少
那么在抓包工具中仔细找找对应的ip
往下翻就找到了这个百度的IP
我们找到第一个百度的ip
来分析下数据包
来看看下一个数据包
来仔细看看
回包还有一个另外的seq等于0
看看下一个包
总结一下这次访问百度的3次握手的过程就是
第一次握手,我访问了百度,代表我请求和百度建立连接,发送了一个SYN(seq=0)
第二次握手,百度收到请求包后,给我回包,也向我请求建立连接,SYN(seq=0新生成随机数 ack=1代表同意建立连接)
第三次握手,我收到百度的包之后,我回复百度SYN(seq=1 ack=1)此时双方建立连接,然后就是通过https协议传输网页数据了,参考上图过程。
四次挥手实验
找到最后的四次挥手的过程数据包
第一次挥手
第二次挥手
第三次挥手
第四次挥手
总结先就是
以上是关于第二季_06_网络基础_TCP/UDP协议的主要内容,如果未能解决你的问题,请参考以下文章
Java基础__慕课网学习(25):Java第二季4.7 UML与PowerDesigner在Java设计中的应用,找了一篇比较好的博客,转载在这里