java实现UDP及TCP通信
简介
UDP(User Datagram Protocol)用户数据报协议,TCP(Transmission Control Protocol) 传输控制协议,是传输层的两个重要协议。
UDP是一种无连接、不可靠传输的协议。其将数据源IP、目的地IP和端口封装成数据包,不需要建立连接,每个数据包的大小限制在64KB内;发送不管对方是否准备好,接收方收到也不确认,故是不可靠的;可以广播发送,发送数据结束时无需释放资源,开销小,速度快。UDP协议适合于即时通信场景,丢失少量数据包也不影响,例如语音通话、视频等。
TCP协议的使用必须双方先建立连接,即是一种面向连接的可靠通信协议。传输前,采用“三次握手”方式建立连接。在连接中可进行大数据量的传输 。连接、发送数据都需要确认,且传输完毕后,还需释放已建立的连接,通信效率较低。TCP协议适用于对信息安全要求较高的场景,例如文件下载等需要安全的数据通信。
Internet协议(IP)
Internet协议类 — InetAddress ,主要包括以下API:
public static InetAddress getLocalHost() | 返回本主机的地址对象 |
public static InetAddress getByName(String host) | 得到指定主机的IP地址对象,参数是域名或者IP地址 |
public String getHostName() | 获取此IP地址的主机名 |
public String getHostAddress() | 返回IP地址字符串 |
public boolean isReachable(int timeout) | 判断是否可在指定毫秒内连通该IP地址对应的主机 |
//本机ipInetAddress ip1=InetAddress.getLocalHost();System.out.println(ip1.getHostName());System.out.println(ip1.getHostAddress());//域名IPInetAddress ip2=InetAddress.getByName("www.baidu.com");System.out.println(ip2.getHostAddress());InetAddress ip3=InetAddress.getByName("112.80.248.75");System.out.println(ip3.getHostAddress());//判断是否可以连通 pingSystem.out.println(ip3.isReachable(5000));
使用UDP通信
假定从客户端(clientP)给服务端(serverP)发消息,我们先实现客户端发消息功能。
首先创建DatagramSocket对象socket,作为发送端UDP对象不需要定义端口号,使用随机分配的就可以了。
然后使用DatagramPacket:数据包对象,将我们的数据内容进行包装,在这里需要设置好接收端口号。
最后使用send方法把数据包发出去。
释放通信资源
DatagramSocket socket=new DatagramSocket();System.out.println("本机端口:"+socket.getLocalPort());//发送端端口号for (int i = 0; i < 5; i++) {//内容byte[] buff = ("你好 "+i).getBytes();DatagramPacket packet = new DatagramPacket(buff, buff.length,InetAddress.getLocalHost(), 8888);//接收端口//发送socket.send(packet);}socket.close();
再来实现服务端接收功能。
首先也是创建DatagramSocket对象socket,作为接收端UDP对象就需要定义端口号了,与服务端一致。
然后使用DatagramPacket,数据包对象,来存放我们需要接收的内容数据包。
最后使用receive方法把数据包收回来。
DatagramSocket socket=new DatagramSocket(8888);for (int i = 0; i < 5; i++) {//内容byte[] buff = new byte[1024 * 10];DatagramPacket packet = new DatagramPacket(buff, buff.length);//接收socket.receive(packet);//数据int len = packet.getLength();//获取收到内容的长度String rs = new String(buff, 0, len);System.out.println("收到 " +packet.getSocketAddress().toString()+":"+ rs);}socket.close();
以上就实现了客户端往服务端发送消息。这个实现的还只是单方面通信,那我们如何实现互相通信呢。
实现CS互通信
基于前面内容我们知道如何实现一方给另一方发消息,这里我们加一个线程进行反过来操作就实现了一个简单的互相通信。
服务端
我们设置一个线程来进行数据接收打印,在主线程进行数据发送,再根据关键字识别进行通信中断功能。
public class serverP {public static void main(String[] args) throws Exception {System.out.println("服务端+++");Thread t=new myThread();//服务端接收线程t.start();//发送 对象DatagramSocket socketp =new DatagramSocket();Scanner sc=new Scanner(System.in);while(true) {//内容String msg=sc.nextLine();byte[] buff = msg.getBytes();DatagramPacket packet = new DatagramPacket(buff, buff.length,InetAddress.getLocalHost(), 8888);//接收socketp.send(packet);if("再见".equals(msg)) {socketp.close();System.out.println("断开连接~");break;}}}
}/*** 接收线程*/
class myThread extends Thread{@Overridepublic void run() {//对象DatagramSocket socket= null;try {socket = new DatagramSocket(8889);} catch (SocketException e) {e.printStackTrace();}while (true) {//内容byte[] buff = new byte[1024 * 10];DatagramPacket packet = new DatagramPacket(buff, buff.length);//接收try {socket.receive(packet);} catch (IOException e) {e.printStackTrace();}//数据int len = packet.getLength();//获取收到内容的长度String rs = new String(buff, 0, len);System.out.println("收到 " +packet.getSocketAddress().toString()+":"+ rs);if("再见".equals(rs)) {socket.close();break;}}}
}
客户端,类似的有:
public class clientP {public static void main(String[] args) throws Exception {System.out.println("客户端+++");Thread t=new myThreadC();//服务端接收线程t.start();//发送 对象DatagramSocket socket=new DatagramSocket();Scanner sc=new Scanner(System.in);while(true) {//内容String msg=sc.nextLine();byte[] buff = msg.getBytes();DatagramPacket packet = new DatagramPacket(buff, buff.length,InetAddress.getLocalHost(), 8889);//接收socket.send(packet);if("再见".equals(msg)) {socket.close();System.out.println("断开连接~");break;}}}
}/*** 接收线程*/
class myThreadC extends Thread{@Overridepublic void run() {//对象DatagramSocket socket= null;try {socket = new DatagramSocket(8888);} catch (SocketException e) {e.printStackTrace();}while (true) {//内容byte[] buff = new byte[1024 * 10];DatagramPacket packet = new DatagramPacket(buff, buff.length);//接收try {socket.receive(packet);} catch (IOException e) {e.printStackTrace();}//数据int len = packet.getLength();//获取收到内容的长度String rs = new String(buff, 0, len);System.out.println("收到 " +packet.getSocketAddress().toString()+":"+ rs);if("再见".equals(rs)) {socket.close();break;}}}
}
至此我们实现了UDP互相发消息

TCP通信
java中只要是使用java.net.Socket类实现通信,底层即是使用了TCP协议。
public Socket(String host , int port),创建发送端的Socket对象与服务端连接,参数为服务端程序的ip和端口。
方法:getOutputStream、getInputStream,分别是获得字节输出、输入流对象。
public ServerSocket(int port),注册服务端端口。
方法:accept,等待接收客户端的Socket通信连接,连接成功返回Socket对象与客户端建立端到端通信
具体来说,客户端发送实现:
创建客户端的Socket对象,请求与服务端的连接。
使用socket对象调用getOutputStream()方法得到字节输出流。
使用字节输出流完成数据的发送,发送一行内容就要flush。
释放资源:关闭socket管道。
Socket socket=new Socket("127.0.0.1",6666);OutputStream os= socket.getOutputStream();PrintStream ps=new PrintStream(os);while(true) {ps.println("hello~");ps.flush();}
服务端接收:
创建ServerSocket对象,注册服务端端口。
调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象。
通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
释放资源:关闭socket管道
ServerSocket serverSocket=new ServerSocket(6666); Socket socket=serverSocket.accept(); InputStream is=socket.getInputStream();BufferedReader br=new BufferedReader(new InputStreamReader(is));String msg;while((msg=br.readLine())!=null){System.out.println(socket.getRemoteSocketAddress()+" "+msg);}
先运行服务端,然后打开客户发送端,成果发送。

相关文章:

java实现UDP及TCP通信
简介UDP(User Datagram Protocol)用户数据报协议,TCP(Transmission Control Protocol) 传输控制协议,是传输层的两个重要协议。UDP是一种无连接、不可靠传输的协议。其将数据源IP、目的地IP和端口封装成数据包,不需要建立连接,每个…...

深度学习-第T1周——实现mnist手写数字识别
深度学习-第T1周——实现mnist手写数字识别深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、归一化4、可视化图片5、调整图片格式四、构建简单的CNN网络五、编译并训练模型1、设置超参数2、编写训练函数六、预…...
质量保障(QA)和质量控制(QC)
质量保证和质量控制是比较容易混淆的一组概念。定义实施质量保证是执行过程组的一个过程,而质量控制是监控过程组的一个过程。质量保证的定义:审计质量要求和质量控制测量结果,确保采用合理的质量标准和操作性定义的过程。简单地说࿰…...

你真的会用三元运算符吗?
在我们日常搬砖中,我们经常会看到三元运算符,但是你了解三元运算符到底是怎么用吗?接下来我们就下来详细介绍一下三元运算符大厂面试题分享 面试题库前后端面试题库 (面试必备) 推荐:★★★★★地址&#x…...

TIA博途中使用SCL语言实现选择排序算法并封装成FC全局库
TIA博途中使用SCL语言实现选择排序算法并封装成FC全局库 选择排序算法包括升序和降序2种: 升序排列: 第一轮从数据源中找到最小值排在第一位,第二轮从剩下的数据中寻找最小值排在第二位,依次类推,直到所有数据完成遍历;降序排列: 第一轮从数据源中找到最大值排在第一位,…...

【C++修炼之路】24.哈希应用--位图
每一个不曾起舞的日子都是对生命的辜负 哈希应用--位图哈希应用:位图一.提出问题二.位图概念三.位图代码四.位图应用五.经典问题哈希应用:位图 一.提出问题 问题: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数&#x…...

4. 字符设备驱动高级--- 下篇
文章目录一、字符设备驱动高级1.1 注册字符设备驱动新接口1.1.1 新接口与旧接口1.1.2 cdev介绍1.1.3 设备号1.1.4 编程实践1.1.5 alloc_chrdev_region自动分配设备号1.1.6 中途出错的倒影式错误处理方法二、字符设备驱动注册代码分析2.1 旧接口register_chrdev2.2 新接口regist…...

ChatGPT介绍以及一些使用案例
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
PCL 点云高斯混合聚类(GMM)
文章目录 一、简介二、算法实现三、实现效果参考资料一、简介 与k均值使用原型向量来刻画聚类结构不同,高斯混合聚类(Mixture-of-Gaussian)采用了概率模型来表达聚类原型。从名字中就可以知晓,该方法将会结合高斯分布来进行聚类过程,该分布的概率密度函数定义如下所示: p (…...
Docker学习(十六)踩坑,如何将对容器的修改同步到基础镜像中
目录1.背景2.解决方法1)将容器文件进行归档2)创建一个新的 Dockerfile3)构建新的基础镜像3.注意事项4.commit命令踩坑记录1.背景 最近接手了一个docker服务,现需要对镜像进行修改,原始的 Dockerfile 已经丢失ÿ…...

食品与疾病关系预测赛题
和鲸平台数据分析实战 题目:食品与疾病关系预测算法赛道 一、赛题描述 食品与疾病关系预测算法赛道 越来越多的证据表明,食物分子与慢性疾病之间存在关联甚至治疗关系。营养成分可能直接或间接地作用于人类基因组,并调节参与疾病风险和疾病…...
Symbol
Symbol是ES6新增的一种基本数据类型 它用来表示独一无二的值, 通过Symbol函数生成 Symbol前面不能加new ,创建symbol类型指的时候传入一个参数,这个参数需要是字符串 使用Symbol函数创建一个symbol类型值,可以给它传入一个字符串参数…...
NC65 对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。
1、对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。 解决方案: 1、在期初余额节点,按Ctrl+ALT+A重建期初凭证; 2、到结账节点,重建余额表,选择有问题的财务核算账簿,注意:会计期间要放空; 3、到期初余额节点,将刚才删除期初数据的…...

位运算相关
文章目录一、求1的个数二、另类加法三、数组中出现一次的数字四、数组中出现一次的数字变形一、求1的个数 二进制中1的个数 法一:逐位判断 根据与&运算 n&10,说明n的最右边一位为0 n&11,说明n的最右边一位为1 所以思路就是&…...

Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号
首先区分一下Linux信号跟进程间通信中的信号量,它们的关系就犹如老婆跟老婆饼一样,没有一毛钱的关系。 信号的概念 信号的概念:信号是进程之间事件异步通知的一种方式,属于软中断。比如:红绿灯是一种信号,…...
锯齿数组 - 贪心
文章目录锯齿数组 -贪心(不过挺像滑动窗口的)1144. 递减元素使数组呈锯齿状锯齿数组 -贪心(不过挺像滑动窗口的) 1144. 递减元素使数组呈锯齿状 题目链接:1144. 递减元素使数组呈锯齿状 题目大意:给你一个…...
[CVPR 2022] Balanced Contrastive Learning for Long-Tailed Visual Recognition
Contents IntroductionMethodPreliminariesBalanced Contrastive Learning (BCL)Drawbacks of SCLClass-averagingClass-complementLower bound of BCLOptimization with Logit CompensationFrameworkExperimentReferencesIntroduction 作者发现对于在长尾数据集上,Supervised…...
23种设计模式-工厂模式
工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而无需将具体的对象创建逻辑暴露给客户端。在Java中,工厂模式常常用于创建复杂对象或对象的构造过程涉及到多个步骤的情况。 在Android开发中,工厂模式也经常被使用&am…...

Linux操作系统学习(进程等待)
文章目录进程等待进程等待的必要性如何进程等待waiwaitpid验证进程等待 我们知道fork函数可以创建一个子进程,而子进程通常是替父进程完成一些任务,而父进程在fork之后需要通过wait/waitpid等待子进程退出。这就是进程等待 进程等待的必要性 通过获…...
Docker学习(十八)load 和 import 命令的区别
Docker 中有两个命令可以将本地文件系统中的 tar 文件导入到 Docker 中:docker load 和 docker import。尽管它们的作用类似,但它们之间有一些重要的区别。 1.使用方式的不同: docker load 的使用示例: docker load --input tes…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...