Java网络编程——UDP通信原理

一、TCP和UDP概述

传输层通常以TCP和UDP协议来控制端点与端点的通信

TCPUDP
协议名称传输控制协议用户数据包协议
是否连接面向连接的协议。数据必须要建立连接无连接的协议,每个数据报中都给出完整的地址信息,因此不需要事先建立发送方和接受方的连接
是否可靠可靠协议。确保收方完全地获取发送方所发送的全部数据不可靠协议。发送方所发送的数据报并不一定以相同的次序到达接收方。
可以传输的数据大小传输数据大小不受限制。一旦连接建立,双方可以按统一的格式传输大的数据传输数据时是有大小限制的。每个被传输的数据报必须限定在64KB之类
数据传输方式IO流DatagramPacket

二、UDP

1.UDP通信概述

UDP协议是一种对等通信的实现,发送方只需要接受方的IP(地址)和Port(端口),就可以直接向它发送数据,不需要线连接。每个程序都可以作为服务器,也可以作为客户端。UDP是一种无连接的传输协议,每个数据报的大小限定在64KB以内。数据报是一个在网络上发送的独立信息,它的到达。到达时间以及内容本身等都不能得到保证。这种传输方式是无序的,也不能确保绝对的安全可靠,但它很简单也具有较高的效率。
使用UDP协议进行数据传输是,需要将需要传输数据定义为数据报(DatagramPaket),在数据报中指明数据所要到达Socket(主机地址和端口号),然后再将数据报发送出去。实例化DatagramPacket时使用参数port和没有使用参数port的区别在与,提供port的一方可以让别人主动发送消息过来,而没有参数port的则会在发送消息时自动绑定一个本地没有使用的端口。在接收到发送的数据报(DatagramPaket)时,不仅可以获取数据,还可以获得发送方的IP和Port,这样就可以向发送方发送数据,因此,本质上二者是对等的。

2.UDP通信特点

1、UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的原地址或目的地址,它在网络上任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
2、UDP不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频视频和普通数据在传输时使用UDP较多,因为它们即使偶尔丢一两个数据包,也不会对接收结果产生太大的影响。

3.UDP通信传输实现的基石

UDP通信的Socket使用DatagramSocket类实现,数据报使用DatagramPaket实现

3.1、DatagramPake常用方法

InetAddress getAddress()得到发送方IP地址
int getPort()得到发送方的端口号
byte[] getData()返回接收缓冲区,这是一个byte[]
int getLength()接收字节的真实大小,通常用于从byte[]中提取出有效数据
int getOffset()返回将要发送或则接收的数据偏移量

3.2、DatagramSocket常用方法

DatagramSocket()空构造函数
DatagramSocket(int port)指定通信端口
void receive(DatagramPaket p)接收数据报
void send(DatagramPaket p)发送数据报
void close()关闭Socket

4.UDP通信实现原理

无论一个UDP通信程序的功能多么功能齐全,程序多么复杂,七基本结构都是一样的,都包括以下四个基本步骤
1、在接收端指定一个端口号来创建DatagramSocket,然后创建一个接收数据报(DatagramPaket),使用recevie方法等待发送方请求报文,这将阻塞服务器线程
2、在发送方创建一个DatagramSocket,使用接收方的IP和端口来创建发送数据报(DatagramPaket),使用send方法发送。现在接收方的recevie方法被唤醒,同时会将发送方的数据报内容填充到接收方的DatagramPaket中。
3、接收方从发送方的数据报中获得发送方的IP和端口,使用它们构造一个发送数据报,然后发送给发送方,这样就实现了发送方和接收方的通信
4、在通信完成后,在客服端和服务端中分别关闭Socket

5.UDP通信原理(代码实现)

代码如下(发送端):

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SendMessage {public static void main(String[] args) throws Exception {
// 创建发送端Socket对象
DatagramSocket sendSocket = new DatagramSocket();
// 准备需要发送的数据
String message = "hello";
// 创建一个缓冲区
byte[] messageByte = message.getBytes();
// 获取缓冲区中数据的真实长度
int messageLen = message.length();
// InetAddress实例化获取本机通信地址
InetAddress address = InetAddress.getLocalHost();
// 设置通信端口号
int port = 12345;
// 打包数据
DatagramPacket sendPacket = new DatagramPacket(messageByte, messageLen, address, port);
// 发送数据
sendSocket.send(sendPacket);
// 发送端等待接收端成功接收信息后返回的回应
// 创建一个缓冲区,容量尽量设置大一点因为不知道发送过来的信息有多大
byte[] recevieByte = new byte[1024*10];
int len = recevieByte.length;
// 接收数据报
DatagramPacket receivePacket = new DatagramPacket(recevieByte, len);
// 接收数据
sendSocket.receive(receivePacket);
// 获取接收端发送过来的真实长度以及数据
byte[] data = receivePacket.getData();
int length = receivePacket.getLength();
String receiveData = new String(data,0,length);
// 获取发送者的IP
address = receivePacket.getAddress();
String ip = address.getHostAddress();
System.out.println("接收来自:"+ip+"的数据,内容是:"+receiveData);
// 关闭资源
sendSocket.close();
}
}

代码如下(接收端):

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class RecevieMessage {public static void main(String[] args) throws Exception {
// 接收消息的端口(与发送端保持一致)
int port = 12345;
DatagramSocket recevieSocket = new DatagramSocket(port);
// 设置缓冲区接收发过来的信息
byte[] receiveByte = new byte[1024*10];
int len = receiveByte.length;
// 接收数据报
DatagramPacket receviePacket = new DatagramPacket(receiveByte, len);
// 接收数据
recevieSocket.receive(receviePacket);
// 获取实际接收到的数据及其大小
byte[] data = receviePacket.getData();
int length = receviePacket.getLength();
String receiveData = new String(data,0,length);
// 获取发送者的IP
InetAddress address = receviePacket.getAddress();
String ip = address.getHostAddress();
System.out.println("接收来自:"+ip+"的数据,内容是:"+receiveData);
// 接收端接收到信息后发送一条确认接收的消息到发送端
String message = "OK";
byte[] messageByte = message.getBytes();
int messageLength = message.length();
// 从已收到的数据报中获取IP和port
address = receviePacket.getAddress();
int port1 = receviePacket.getPort();
//构造新数据报
DatagramPacket sendPacket = new DatagramPacket(messageByte, messageLength, address, port1);
// 发送数据
recevieSocket.send(sendPacket);
// 关闭资源
recevieSocket.close();
}
}

发送端输出结果:

接收端输出结果:

总结

注意:在发送端与接收端启动测试时最好最好先启动接收端,因为这样才能确保信息能发送出去,接收端能接收到信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/414501.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode 013二维区域和检索---矩阵不可变

给定一个二维矩阵 matrix,以下类型的多个请求: 计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2) 。 实现 NumMatrix 类: NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进…

jrebel IDEA 热部署

1 下载 2022.4.1 JRebel and XRebel - IntelliJ IDEs Plugin | Marketplace 2 选择下载好的zip 离线安装IDEA 插件 重启IDEA 3 打开 [Preference -> JRebel & XRebel] 菜单,输入 GUID address 为 https://jrebel.qekang.com/1e67ec1b-122f-4708-87d…

买家福音:亚马逊鲲鹏系统全自动操作助你轻松搞定一切

我一直以来都是亚马逊的忠实用户,但是最近我发现了一款真正令人惊叹的工具,改变了我在平台上的经验。我想分享一下我的感受,最近,我得知并尝试了亚马逊鲲鹏系统,简直是为买家账号管理量身定制的利器。在我账号过多时&a…

旅游行业@2023/24:复苏、繁荣与重构

Mark作为一名热爱旅游的大学生,在2023年,去过很多地方,有因烧烤爆火的淄博;也有因特种兵式旅游再次出名的泰山;还和同学一起自驾去了川西;最近,他就正在计划春节要在哪里度过。 “我可太喜欢旅…

公司用什么软件监控电脑—可以部署|天锐绿盾数据防泄密系统(有行为审计监控功能)防止核心文件数据资料外泄!

天锐绿盾是一款企业内网安全管理软件,专注于为企业提供全面的信息化安全管理解决方案。它通过局域网内文件的透明加密、内网的有效管理等方式,满足不同类型企业用户对信息安全的需求。 天锐绿盾是一款功能强大的企业内网安全管理软件 PC地址:…

MSVS C# Matlab的混合编程系列1 - 看似简单的问题引出

前言: 问题提出,如何把Matlab(本文简称MT)的算法集成到Visual Studio(本文简称VS)里面运行? 本文,通过编制一个MT中最简单的加法函数,我们把他做成 MSVS C#能够使用的动态库,说明了MSVS C# 和 MT集成的最…

GO基础进阶篇 (十四)、Http编程

Web基础概念 web应用程序 web程序可以提供浏览器访问的程序。Web应用程序通常采用客户端-服务器模型。客户端是用户使用的Web浏览器或其他Web客户端,而服务器是存储和处理数据的远程计算机。 我们能访问到的任何一个页面或资源,都存在于世界的某一个角落…

css 居中方式

居中分为水平居中和垂直居中 1. 水平居中1.1 文字text-align:center;1.2 盒子1.2.1:inline-block text-align 一 center;1.2.2:absolutetransform 一 父元素 display:relative;子元素 display:absolute; left:50%;transform: translatex(-50%);1.2.3&a…

Git教程学习:03 记录每次更新到仓库

文章目录 1 检查当前文件状态2 跟踪新文件3 暂存已修改的文件4 状态简览5 忽略文件6 查看已暂存和未暂存的修改7 提交更新8 跳过使用暂存区域9 移除文件10 移动文件 现在我们的机器上有了一个 真实项目 的 Git 仓库,并从这个仓库中检出了所有文件的 工作副本。 通常…

git设置代理

git设置代理 git config --global http.proxy 127.0.0.1:7890git查询代理 git config --global http.proxy git取消代理 git config --global --unset http.proxy

揭开UI设计的神秘面纱:如何打造一款让用户爱不释手的移动APP

文章目录 一、目标用户分析二、设计风格和色彩搭配三、布局和导航设计四、交互设计五、视觉元素设计六、响应式设计七、测试和优化八、持续更新和迭代九、团队协作和沟通十、学习和成长《移动APP UI设计与制作(微课版)》编辑推荐内容简介目录 《Flutter入门经典(移动…

matlab simulink 7自由度横向车辆模型

1、内容简介 略 32-可以交流、咨询、答疑 2、内容说明 图一.七自由度车辆动力学模型 纵向力平衡方程: ① 侧向力平衡方程: ② 绕Z轴力矩平衡方程: ③ 四个车轮的力矩平衡方程: ④ 上述方程中:δ为前轮转角&#x…