TCP协议与UDP协议

我们为什么需要TCP/UDP协议?

  现代人的日常生活都离不开手机与电脑,但真的是手机与电脑吗?如果手机与电脑都断网了,你还会依赖它们吗?所以,我觉得大家归根结底其实是离不开网络。

  如今网络全球化,整个世界都是同一个局域网了,每天的数据量都多到可怕,网络的使用需要管理,就像路上开车一样,如果没有交警和信号灯,肯定就乱糟糟了。这时候就需要网络通信协议来制定标准加以管理。

  但世界上国家这么多,开发人员这么多。如果每个人都使用自己定义的一套通信标准,就像一个人说中文另一个说英语,会无法交流。这时候,就需要统一标准协议, TCP/IP 协议族,就是最常用的网络通信协议,而TCP协议与UDP协议是TCP/IP 协议族的重要组成部分。

网络通信协议

   国际标准化组织(ISO,即International Organization for Standardization)定义了网络通信协议的基本框架,被称为OSI(Open System Interconnect,即开放系统互联)模型。用于约定速率、传输代码、代码结构、传输控制步骤、出错控制等的标准。

   OSI模型制定的七层标准模型,分别是:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。如下图所示:
在这里插入图片描述
   OSI模型是参考模型,TCP/IP 协议族则是具体的实现。

   TCP/IP协议族,不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。TCP/IP协议族,也是按照层次划分,共四层:应用层,传输层,网络层,链路层。其与OSI模型的对照表格如下:
在这里插入图片描述
   不难看出,TCP/IP 与 OSI 在分层模块上稍有区别。OSI 参考模型注重“通信协议必要的功能是什么”,而 TCP/IP 则更强调“在计算机上实现协议应该开发哪种程序”。

TCP

  TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,当应用程序采用 TCP 发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。TCP 为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此外还具备“流控制(流量控制)”、“拥塞控制”、提高网络利用率等众多功能。

三次握手

  三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。流程图如下:
在这里插入图片描述

  • 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
  • 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
  • 第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

四次挥手

  四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

  由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。中断连接端可以是客户端,也可以是服务器端。

  流程图如下:
在这里插入图片描述

  • 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
  • 第二次挥手:服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。
  • 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
  • 第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。

  以上都是TCP协议的理论部分,接下来通过Java代码,看看如何实现的:

  服务端,分为四个步骤:

  • 1、指定端口 使用ServerSocket创建服务器
  • 2、阻塞式等待连接 accept
  • 3、操作: 输入输出流操作
  • 4、释放资源
public class Server {
	public static void main(String[] args) throws IOException {
		System.out.println("-----Server-----");
		// 1、指定端口 使用ServerSocket创建服务器
		ServerSocket server =new ServerSocket(8888);//8888,指定端口号
		// 2、阻塞式等待连接 accept
		Socket  client =server.accept();  //阻塞式,会等待
		System.out.println("一个客户端建立了连接");
		// 3、操作: 输入输出流操作
		DataInputStream dis =new DataInputStream(client.getInputStream());//IO流操作
		String data =dis.readUTF();
		System.out.println(data);
		// 4、释放资源 
		dis.close();
		client.close();
		
		server.close();//关闭服务器,一般不关
	}
}

  客户端,分为三个步骤:

  • 1、建立连接: 使用Socket创建客户端 +服务的地址和端口
  • 2、操作: 输入输出流操作
  • 3、释放资源
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("-----Client-----");
		//1、建立连接: 使用Socket创建客户端 +服务的地址和端口
		Socket client =new Socket("localhost",8888);//地址+端口
		//2、操作: 输入输出流操作
		DataOutputStream dos =new DataOutputStream(client.getOutputStream());//IO流操作
		String data ="hello";
		dos.writeUTF(data);
		dos.flush();
		//3、释放资源 
		dos.close();
		client.close();
	}
}

  TCP是对IO流进行操作的,可以使用不同的流来达到传输不同类型文件的目的。消息收发两端有主次之分,可以在服务端中使用多线程,达到同时与多个客户端通信的目的。

UDP

  UDP 是无连接的,不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。

  UDP的特点:

  • UDP 不提供复杂的控制机制,利用 IP 提供面向无连接的通信服务。
  • 并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况,UDP 也无法进行流量控制等避免网络拥塞行为。
  • 此外,传输途中出现丢包,UDP 也不负责重发。甚至当包的到达顺序出现乱序时也没有纠正的功能。
  • 如果需要以上的细节控制,不得不交由采用 UDP 的应用程序去处理。
  • UDP 常用于一下几个方面:1.包总量较少的通信(DNS、SNMP等);2.视频、音频等多媒体通信(即时通信);3.限定于 LAN 等特定网络中的应用通信;4.广播通信(广播、多播)。

  通过Java代码使用UDP:

  接收端,分为五个步骤:

  • 1、使用DatagramSocket 指定端口 创建接收端
  • 2、准备容器 封装成DatagramPacket 包裹
  • 3、阻塞式接收包裹receive​(DatagramPacket p)
  • 4、分析数据
  • 5、释放资源
public class UdpServer {

	public static void main(String[] args) throws Exception {
		System.out.println("接收方启动中.....");
		// 1、使用DatagramSocket  指定端口 创建接收端
		DatagramSocket server =new DatagramSocket(6666);//接收端的端口
		// 2、准备容器 封装成DatagramPacket 包裹
		byte[] container =new byte[1024*60];
		DatagramPacket packet = new DatagramPacket(container,0,container.length);
		// 3、阻塞式接收包裹receive​(DatagramPacket p)
		server.receive(packet); //阻塞式
		// 4、分析数据
		 byte[]  datas =packet.getData();
		 int len = packet.getLength();
		 System.out.println(new String(datas,0,len));
		// 5、释放资源
		 server.close();
	}
}

  发送端,分为五个步骤:

  • 1、使用DatagramSocket 指定端口 创建发送端
  • 2、准备数据 一定转成字节数组
  • 3、 封装成DatagramPacket 包裹,需要指定目的地
  • 4、发送包裹send​(DatagramPacket p)
  • 5、释放资源
public class UdpClient {
	public static void main(String[] args) throws Exception {
		System.out.println("发送方启动中.....");
		 // 1、使用DatagramSocket  指定端口 创建发送端
		DatagramSocket client =new DatagramSocket(8888);//发送端的端口
		 //2、准备数据 一定转成字节数组
		String data = "上海尚学堂";
		byte[] datas = data.getBytes();
		 //3、 封装成DatagramPacket 包裹,需要指定目的地
		DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
				new InetSocketAddress("localhost",6666));//接收端的端口
		//4、发送包裹send​(DatagramPacket p) * 
		client.send(packet);
		// 5、释放资源
		client.close();
	}
}

  需要注意的是,UDP中不存在主次关系,两边都可以同时发送和接受数据(可通过多线程实现)。所以两边都需要占用一个端口,同台设备同一协议下端口不可重复使用。

TCP与UDP的对比

  TCP协议和UDP协议是传输层的两种协议。Socket是传输层供给应用层的编程接口,所以Socket编程就分为TCP编程和UDP编程两类。

  在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。

  TCP 和 UDP 的优缺点无法简单地、绝对地去做比较,这两种传输方式都在实际的网络编程中使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则可以通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据传递。TCP 和 UDP 应该根据应用的目的按需使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值