目录
一、简介UDP和TCP来源
OSI七层结构
TCP/IP协议模型
二、TCP协议:
1、TCP的功能:
2、UDP的代码实现:
3、TCP协议的组成:
4、TCP的连接管理:TCP的三次握手(建立连接)和四次挥手(释放连接)
TCP的三次握手:
TCP三次握手的原因:
TCP的三次握手状态的改变
5、重传的机制:
超时重传:
快速重传:【三次确认ACK】
3、SACK重传:
6、滑动窗口:
7、TCP流量控制
8、TCP的拥塞控制:
拥塞控制的概念:
拥塞控制的四个算法:
1、慢开始:
2、拥塞避免:
3、快重传:
4、快恢复:
三、UDP协议:
1、UDP协议的首部格式:
2、UDP的代码实现
四、总结:UDP和TCP的区别:
一、简介UDP和TCP来源
TCP和UDP是OSI七层结构中的传输层的协议:
为了提高各层之间之间的相互独立,同层只需要根据同层之间的协议相互作用完成本次的功能,而不同层之间是相互提供服务的关系,提高整体的得灵活性,将大问题小化,分工合作完成数据传递。提出OSI七层结构。
OSI七层结构
当然OSI只是一种理想的模型,实际用的是TCP/IP协议
TCP/IP协议模型
二、TCP协议:
传输控制协议 TCP(Transmission Control Protocol)是面向连接 、传输字节流,可靠的传输层协议(传输数据前,必须建立连接)。
1、TCP的功能:
TCP “流量控制”、“拥塞控制”等功能来保证“可靠性传输”功能。
可靠性传输:在网络中传输数据,有的数据比较小,一个数据包就可以传完,这时使用UDP协议;有的数据(比如电影视频/音频流等)比较大,这就要求把数据分成报文段传输,分成的每个报文段就是一个数据包,依次传输和接收。传输的过程中有可能丢包,这就导致某些数据包缺失接收端无法打开整个文件,但是网络层不负责保证可靠传输,这就要依靠传输层的TCP协议来实现可靠传输。
流量控制:TCP协议具备流量控制的功能,简单点说,服务器功能强大发数据很快,接收端无法及时处理就会给服务器发信息,告诉服务器减缓发送数据的速度。
拥塞控制:TCP协议具备拥塞控制的功能。例如:两台主机在传输数据包的时候,如果发送方迟迟没有收到接收方反馈的ACK,那么发送方就会认为它发送的数据包丢失了,进而会重新传输这个丢失的数据包。如果重新传输发送的数据包数量过多,就会导致网络的拥堵,从而瘫痪。拥塞控制主要通过慢开始、拥塞避免、快重传、快恢复来控制避免产生拥塞。
2、UDP的代码实现:
TCP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt(); * 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、开启监听,用函数listen();
5、接收客户端上来的连接,用函数accept();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
8、关闭监听;
package com.shang.计算机网路;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try(ServerSocket Server=new ServerSocket(8080);) {
//获取链接的主机ip地址
Socket socket = Server.accept();
System.out.println("链接的客户端ip地址"+socket.getRemoteSocketAddress());
} catch (Exception e) {
// TODO: handle exception
}
}
}
TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
package com.shang.计算机网路;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try (Socket client=new Socket("192.168.1.111",8080);){
//客户端接收服务器传入的数据
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("提货的验证码:"+reader);
} catch (Exception e) {
}
}
}
3、TCP协议的组成:
-
- 首部组成:两端两号一偏移数据,保留六个常见标记位,一口一校验一急指针
TCP首部的内容的含义:
- 源窗口:4字节 表示发送端口。
- 八个控制位:8 位 用于传递过程,传递控制标志位。
- 保留:4 位 保留为今后使用。默认为0.
- 数据偏移:数据部分距离报文首部的偏移量。【TCP首部长度】
- 确认号:4 字节 期望收到对方下一个报文的第一个字节的序号。
- 序号:8字节 本报文段的第一个数据的第一个字节的序号。
- 目的端口:4 字节 表示接收端口。
ACK:确认位
SYN:同步位
FIN:终止位
PSH :推送位
URG :紧急位
RST :复位位
- 窗口:接收方让发送方设置器发送窗口的依据【接收方的数据缓存空间是有限的】
- 紧急指针:16 位 指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。
- 检验和:检验包括数据部分和首部两个部分,校验时在在报文段的前面加上12字节的伪首部。
4、TCP的连接管理:TCP的三次握手(建立连接)和四次挥手(释放连接)
-
TCP的三次握手:
-
- 注意区分ACK和ack的去区别:
- ACK:确认标记。
- ack:确认号
-
第一次握手:
- 客户端先向服务器发送一个同步数据包(报文段)。
- 数据包的TCP首部内容:同步SYN=1,确认ACK=0,序号seq=x
- 根据TCP首部内容,表示这是一个请求建立连接的数据包,其中seq=x为所传送数据的第一个字节的序号。
-
第二次握手:
- 服务器收到客户端发送的第一个数据包后,根据SYN=1与ACK=0,判断出为主动建立连接的数据包。
- 若服务器同意连接,则服务器发送一个数据包进行回应。
- 数据包的TCP首部内容:同步SYN=1,确认ACK=1,序号seq=y,确认号ack=x+1
- 确认ACK=1,代表服务器同意连接;
- 序号seq=y的值由服务器指定,表示服务器发送数据时的第一个数据字节的序号;
- 确认号ack=x+1,表示已经收到客户端发送的x个字节数据,并告诉客户端下次应从数据的第x+1个字节开始发送;
-
第三次握手:
- 客户端收到服务器的确认之后,再给服务器发送一个数据包。
- 数据包的TCP首部内容:同步SYN=0,确认ACK=1,序号seq=x+1,确认号ack=y+1
- SYN=0,表示双方已同意建立连接;
- 确认ACK=1,表示收到服务器的确认数据包;
- 序号seq=x+1,表示发出的数据包就是数据的第x+1个字节;
- 确认号ack=y+1,表示收到服务器发送y字节数据,并告诉服务器下次应从数据的第y+1个字节开始发送。
- 注意区分ACK和ack的去区别:
TCP三次握手的原因:
- 在建立TCP连接过程中的前两次握手:①客户端向服务器发出建立连接的请求、② 服务器向客户端确认这个请求,足以证明客户端与服务器之间的网络是畅通的。
- 如果没有最后一个数据包确认(第三次握手),假设一个特殊场景:客户端先发出一个建立连接的请求数据包,由于网络原因,客户端在设定的超时时间内,还未收到服务器的确认数据包。于是发出第二个建立连接的请求数据包,这次网路通畅,数据包很快到达服务器,服务器的确认数据包也很快就到达客户端。于是客户端与服务器开始传输数据。但是客户端第一次发出的建立连接的请求数据包到达服务器,服务器以为是再次建立连接,所以又发出一个确认数据包。由于客户端已经收到了一个确认数据包,所以会忽略服务器发来的第二个确认数据包,但是服务器发出确认数据包之后就要一直等待客户端的回复,而此时的客户端永远也不会回复服务器。由此服务器无效等待,造成资源浪费。如果过于频繁会导致服务器停止响应。
- 所以,三次握手的主要作用是为了避免重复连接,防止旧的重复连接引起连接混乱问题。
- 另外,通过三次握手,可以得到一个确认的可靠初始化序列号seq,用于进行可靠性传输。而如果只有2次握手,则无法初始化序列号seq。
- 综上所述,TCP协议最少需要通过3次握手建立连接。当然, TCP 连接也通过4次握手或5次握手建立连接,实现 TCP 连接的稳定性,但3次握手是最节省资源的连接方式。
-
TCP的三次握手状态的改变
-
- 客户端发出请求建立连接的数据包之后进入SYN-SENT状态,表示发送了请求建立连接的同步数据包。
- 服务器收到客户端发出的请求建立连接的数据包之后,结束LISTEN状态,进入SYN-RCVD状态并向A发出确认数据包。
- 客户端收到确认数据包之后,结束SYN-SENT状态,进入ESTABLISHED状态,并向服务器发送确认数据包。
- 服务器收到客户端的确认数据包之后,结束SYN-RCVD状态,进入ESTABLISHED状态。
- 客户端与B都进入ESTABLISHED状态之后,开始传输数据,由此完成三次握手。
-
TCP的四次挥手:
-
第一次挥手:
- 首先客户端向服务器发送连接释放的请求报文(数据包),并停止发送数据。
- 在连接释放报文(数据包)的TCP首部中:终止FIN=1,确认ACK = 0
- 终止FIN=1,意味着客户端要主动释放客户端—>服务器的TCP连接;序号位seq为u,u值由客户端指定。随后等待B的确认。
-
第二次挥手:
- 服务器收到连接释放的报文之后,给客户端发送确认报文。从客户端到服务器这个方向上的连接就释放了,TCP连接处于半关闭状态。此时客户端无法发送数据给服务器,但是服务器还可以发送数据给客户端,客户端仍可以接收。
- 在服务器发送给客户端确认报文的TCP首部中:终止FIN=0,确认ACK=1,序号位seq=v,确认号ack=u+1
- 确认ACK=1表示收到了客户端发送的数据包,同意客户端释放连接;
-
第三次挥手:
- 若服务器已经没有向客户端发送的数据了,其应用进程就通知TCP释放连接,并向客户端发送确认报文。
- 在确认报文的TCP首部中:确认ACK=1,终止FIN=1
- 确认ACK=1,表示服务器已经把需要发给客户端的数据发完了;
- 终止FIN=1,表示服务器要释放服务器—>客户端的TCP连接;
- 此后服务器不再向客户端发送数据,但能接收数据。
-
第四次挥手:
- 客户端收到服务器的连接释放报文段后,向服务器发出确认报文。
- 在确认报文的TCP首部中:确认ACK=1,终止FIN = 0
- 确认ACK=1,表示收到服务器的确认报文,并同意服务器释放连接;
5、重传的机制:
-
超时重传:
- 是一种机制,在重发超时的时间间隔内,没有等到确认应答,发送端就可以认为数据包已经丢失,就会重新发送该数据。所以,即使产生了丢包,仍然能够保证数据能够到达接收端,实现可靠性传输。
- 两种发生超时重传的情况:
- 数据包丢失的情况
- 确认应答丢失的情况
- 两种发生超时重传的情况:
- 是一种机制,在重发超时的时间间隔内,没有等到确认应答,发送端就可以认为数据包已经丢失,就会重新发送该数据。所以,即使产生了丢包,仍然能够保证数据能够到达接收端,实现可靠性传输。
-
快速重传:【三次确认ACK】
- TCP协议重传机制的第二种方式是快速重传(Fast Retransmit)机制,它不以时间为驱动,而是以数据驱动重传。快速重传的工作方式是当收到三个相同的 ACK 报文时,会在重传超时过期之前,重传丢失的报文段。但是它存在的问题是重传的时候,是重传之前的一个,还是重传所有
-
3、SACK重传:
- (Selective Acknowledgment 选择性确认)【解决在快速重传的已接收的数据怎么办】
- 这种方式需要在 TCP 首部「选项」字段里加一个 SACK的东西,它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。
- (Selective Acknowledgment 选择性确认)【解决在快速重传的已接收的数据怎么办】
-
6、滑动窗口:
- 概述:
- 是TCP实现流量控制的一种机制。
- 发送方和接收方分别维护自己的缓冲区,这个缓冲区就是窗口。发送方得窗口由接收方的TCP首部的窗口决定。
- 发送方得窗口分为:
- 已发送已确认
- 已发送未确认
- 未发送未超出窗口的范围
- 未发送但超出窗口的大小
- 接收方的窗口分为:【接收方读取窗口的内容,并不断的去人通知发送方,窗口向前滑动。接收方通过改变窗口的大小,可以控制发送方得速度,从而实现流量控制】
- 接收已确认
- 未接收但可接收的
- 概述:
-
滑动窗口的作用:
- 问题:
- TCP在传输数据的时候,如果数据比较大的时候,数据会被拆分发送。每发送一次就需要的等待一次的确认,当上一个数据包收到了才能进行下一次的数据放送。这样的往返时间越长,通信的效率就越低。
- 解决:
- 引入窗口的概念:
- TCP引入了窗口的概念。窗口的大小就是指定无需等待去人应答,而可以继续发送数据的最大值。
- 窗口的实现:
- 实际上就是在操作系统开辟一个缓存空间,发送方主机在等待确认应答返回数据之前,必须在缓冲区中保留已发送的数据。按期接收到确认应答,就清除缓冲取得数据。即使往返时间比较长,也不会降低网络的通信效率。
- TCP协议通过滑动窗口的机制解决了流量控制和乱序重排
- 引入窗口的概念:
- 问题:
- 客户端向服务端发送请求数据报文。
- 服务端收到请求报文后,发送确认报文和 80字节的数据,于是可用窗口 Usable 减少为 120字节,同时 SND.NXT 指针也向右偏移 80 字节后,指向 321,这意味着下次发送数据的时候,序列号是 321。
- 客户端收到 80 字节数据后,于是接收窗口往右移动 80 字节,RCV.NXT 也就指向 321,这意味着客户端期望的下一个报文的序列号是 321,接着发送确认报文给服务端。
- 服务端再次发送了 120 字节数据,于是可用窗口耗尽为 0,服务端无法在继续发送数据。
- 客户端收到 120 字节的数据后,于是接收窗口往右移动 120 字节,RCV.NXT 也就指向 441,接着发送确认报文给服务端。
- 服务端收到对 80 字节数据的确认报文后,SND.UNA 指针往右偏移后指向 321,于是可用窗口 Usable增大到 80。
- 服务端收到对 120 字节数据的确认报文后,SND.UNA 指针往右偏移后指向 441,于是可用窗口 Usable 增大到 200。
- 服务端可以继续发送了,于是发送了 160 字节的数据后,SND.NXT 指向 601,于是可用窗口 Usable 减少到 40。
- 客户端收到 160 字节后,接收窗口往右移动了 160 字节,RCV.NXT 也就是指向了 601,接着发送确认报文给服务端。
- 服务端收到对 160 字节数据的确认报文后,发送窗口往右移动了 160 字节,于是 SND.UNA 指针偏移了 160 后指向 601,可用窗口 Usable 也就增大至了 200。
7、TCP流量控制
简单来讲:流量控制是为了控制发送方发送速率,保证接收方来得及接收。
TCP连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失,从而实现流量控制。
TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (即TCP 利用滑动窗口实现流量控制)
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
8、TCP的拥塞控制:
-
拥塞控制的概念:
- 跟流量控制的区别:流量控制是针对发送和接收方,二拥塞控制是为了降低整个网络的拥塞程度。
- 拥塞控制是针对全局的,整个网络,涉及到所有的主机,路由器,和其他的影响网络传输的因素。
- 拥塞控制就是防止过多的数据注入网络,是网络中的路由器好链路不致过载。
- 什么是拥塞:
- 网络中的某一资源的需求超过了该资源搜能提供的可用部分,网络的性能就回变坏,这就拥塞。
-
拥塞控制的四个算法:
-
1、慢开始:
- 拥塞窗口(只是存放在内存的一个状态变量)cwnd=1,收到确认之后按照指数次增长。
-
-
-
-
2、拥塞避免:
- 防止慢开始增长的过快,导致网络的拥塞程度可能会增加。所以到达设置的门限值ssthresh的时候,就开始拥塞避免。cwnd开始加法增长。
-
3、快重传:
- 当收到三个连续确认,说明数据传送的过程中出现了丢包的现象,所以就实行快重传。就是快速重传。
- 例如:如发送数据包M1~M5,丢失了M3。接收方接连收到不连续的数据包M2、M4,就已经发现丢失了M3,可采用快重传方式。
-
-
-
-
-
4、快恢复:
- 乘法减小的算法,把慢开始的门限值减半【变成当时cwnd的一半】。cwnd也是这值。然后执行拥塞避免算法。
- 快恢复是配套着快重传使用的,快恢复是相对于慢开始算法而言的。使用快恢复算法时,cwnd从较大值开始,通过拥塞避免算法逐渐线性增大,经过较短时间便能恢复比较快的传输速度;使用慢开始算法时,cwnd从1开始,需要较常时间才能达到较快的速度。
-
-
-
三、UDP协议:
- 概述:UDP不提供复杂的控制机制,丢包不重传。
- 使用场景:
- 数据包的内容比较小的时候
- 视屏,音频
- 广播通信。
- 特点:
- 无连接
- 报文传输
- 不可靠的传输
- 支持一对多,一对一,多对一的交互通信。
- 首部开销少。只有8个字节。
-
1、UDP协议的首部格式:
- 四个字段组成:八个字节一个字段两个字节。
-
2、UDP的代码实现
- UDP:与之对应的UDP编程步骤要简单许多,分别如下:
UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接; -
package com.shang.计算机网路; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.nio.charset.StandardCharsets; public class ServerUDP { public static void main(String[] args) { //创建数据,用于接收发送端的数据 byte[] b=new byte[20]; //创建数据包存放发送方的数据 DatagramPacket datepacket=new DatagramPacket(b, b.length); //获取发送方的数据包 datepacket.getData(); try(DatagramSocket socket=new DatagramSocket(8080)) { //接收数据包 socket.receive(datepacket); System.out.println("收到的数据的长度是"+datepacket.getLength()); //处理接收的数据 String result=new String(datepacket.getData(),datepacket.getOffset(),datepacket.getLength(),StandardCharsets.UTF_8); System.out.println(result); byte[] b1= "Ack".getBytes(); //socket.connect(Inet4Address.getByName("127.0.0.1"), 8081); datepacket.setData(b1); socket.send(datepacket); } catch (Exception e) { // TODO: handle exception } } }
UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接; -
package com.shang.计算机网路; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.Inet4Address; public class ClientUDP { public static void main(String[] args) { //数组存入数据 byte[] b= "helloUDP".getBytes(); //将数据放入数据包 DatagramPacket datepacket=new DatagramPacket(b, b.length); datepacket.setData(b); try (DatagramSocket socket=new DatagramSocket()){ //获取socket,设置服务器的地址和端口号 socket.connect(Inet4Address.getLocalHost(),8080); socket.send(datepacket); //接收服务器端的响应 //创建数据,用于接收发送端的数据 byte[] b1=new byte[20]; DatagramPacket datepacket1=new DatagramPacket(b, b.length); //获取发送方的数据包 datepacket1.getData(); socket.receive(datepacket1); System.out.println("收到的数据的长度是"+datepacket1.getLength()); //处理接收的数据 String result=new String(datepacket1.getData(),datepacket1.getOffset(),datepacket1.getLength()); System.out.println(result); } catch (Exception e) { } } }
- UDP:与之对应的UDP编程步骤要简单许多,分别如下:
四、总结:UDP和TCP的区别:
文章来源:https://www.toymoban.com/news/detail-433521.html
-
- 面向连接:TCP协议需要建立连接,仅支持一对一通信;UDP协议无需建立连接,支持一对一、一对多、多对一和多对多的交互通信。
- 可靠传输:TCP协议通过确认应答、连接管理、流量控制、拥塞控制来确保可靠性传输;UDP不保证可靠性传输。
- 性能效率:TCP协议传输效率慢,需要较多的资源开销。UDP协议传输效率快,需要较少的资源开销。
- 首部格式:TCP协议的首部需要20-60个字节,UDP协议需要8个字节。
- UDP在传送数据之前不需要先建立连接,接收方主机在收到 UDP报文后,不需要给出任何确认。虽然 UDP不提供可靠交付,但在某些情况下 UDP却是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等。
- TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这难以避免增加了许多开销,例如:确认应答,流量控制,超时重传以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。
文章来源地址https://www.toymoban.com/news/detail-433521.html
到了这里,关于TCP协议和UDP协议的区别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!