目录

一、简介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+1SYN=0,表示双方已同意建立连接;确认ACK=1,表示收到服务器的确认数据包;序号seq=x+1,表示发出的数据包就是数据的第x+1个字节;确认号ack=y+1,表示收到服务器发送y字节数据,并告诉服务器下次应从数据的第y+1个字节开始发送。

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的东西,它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。     

                        

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和TCP的区别:

        

面向连接:TCP协议需要建立连接,仅支持一对一通信;UDP协议无需建立连接,支持一对一、一对多、多对一和多对多的交互通信。可靠传输:TCP协议通过确认应答、连接管理、流量控制、拥塞控制来确保可靠性传输;UDP不保证可靠性传输。性能效率:TCP协议传输效率慢,需要较多的资源开销。UDP协议传输效率快,需要较少的资源开销。首部格式:TCP协议的首部需要20-60个字节,UDP协议需要8个字节。UDP在传送数据之前不需要先建立连接,接收方主机在收到 UDP报文后,不需要给出任何确认。虽然 UDP不提供可靠交付,但在某些情况下 UDP却是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等。TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这难以避免增加了许多开销,例如:确认应答,流量控制,超时重传以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 

 

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。