当前位置: 首页 > news >正文

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)发消息,我们先实现客户端发消息功能。

  1. 首先创建DatagramSocket对象socket,作为发送端UDP对象不需要定义端口号,使用随机分配的就可以了。

  1. 然后使用DatagramPacket:数据包对象,将我们的数据内容进行包装,在这里需要设置好接收端口号。

  1. 最后使用send方法把数据包发出去。

  1. 释放通信资源

        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();

再来实现服务端接收功能。

  1. 首先也是创建DatagramSocket对象socket,作为接收端UDP对象就需要定义端口号了,与服务端一致。

  1. 然后使用DatagramPacket,数据包对象,来存放我们需要接收的内容数据包。

  1. 最后使用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互通信

基于前面内容我们知道如何实现一方给另一方发消息,这里我们加一个线程进行反过来操作就实现了一个简单的互相通信。

  1. 服务端

我们设置一个线程来进行数据接收打印,在主线程进行数据发送,再根据关键字识别进行通信中断功能。

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;}}}
}
  1. 客户端,类似的有:

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;}}}
}
  1. 至此我们实现了UDP互相发消息

TCP通信

java中只要是使用java.net.Socket类实现通信,底层即是使用了TCP协议。

public Socket(String host , int port)​,创建发送端的Socket对象与服务端连接,参数为服务端程序的ip和端口。

方法:getOutputStream、getInputStream,分别是获得字节输出、输入流对象。

public ServerSocket(int port),注册服务端端口。

方法:accept,等待接收客户端的Socket通信连接,连接成功返回Socket对象与客户端建立端到端通信

具体来说,客户端发送实现:

  1. 创建客户端的Socket对象,请求与服务端的连接。

  1. 使用socket对象调用getOutputStream()方法得到字节输出流。

  1. 使用字节输出流完成数据的发送,发送一行内容就要flush。

  1. 释放资源:关闭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();}

服务端接收:

  1. 创建ServerSocket对象,注册服务端端口。

  1. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象。

  1. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。

  1. 释放资源:关闭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)用户数据报协议&#xff0c;TCP(Transmission Control Protocol) 传输控制协议&#xff0c;是传输层的两个重要协议。UDP是一种无连接、不可靠传输的协议。其将数据源IP、目的地IP和端口封装成数据包&#xff0c;不需要建立连接&#xff0c;每个…...

深度学习-第T1周——实现mnist手写数字识别

深度学习-第T1周——实现mnist手写数字识别深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、归一化4、可视化图片5、调整图片格式四、构建简单的CNN网络五、编译并训练模型1、设置超参数2、编写训练函数六、预…...

质量保障(QA)和质量控制(QC)

质量保证和质量控制是比较容易混淆的一组概念。定义实施质量保证是执行过程组的一个过程&#xff0c;而质量控制是监控过程组的一个过程。质量保证的定义&#xff1a;审计质量要求和质量控制测量结果&#xff0c;确保采用合理的质量标准和操作性定义的过程。简单地说&#xff0…...

你真的会用三元运算符吗?

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

TIA博途中使用SCL语言实现选择排序算法并封装成FC全局库

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

【C++修炼之路】24.哈希应用--位图

每一个不曾起舞的日子都是对生命的辜负 哈希应用--位图哈希应用&#xff1a;位图一.提出问题二.位图概念三.位图代码四.位图应用五.经典问题哈希应用&#xff1a;位图 一.提出问题 问题&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#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介绍以及一些使用案例

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️&#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…...

PCL 点云高斯混合聚类(GMM)

文章目录 一、简介二、算法实现三、实现效果参考资料一、简介 与k均值使用原型向量来刻画聚类结构不同,高斯混合聚类(Mixture-of-Gaussian)采用了概率模型来表达聚类原型。从名字中就可以知晓,该方法将会结合高斯分布来进行聚类过程,该分布的概率密度函数定义如下所示: p (…...

Docker学习(十六)踩坑,如何将对容器的修改同步到基础镜像中

目录1.背景2.解决方法1&#xff09;将容器文件进行归档2&#xff09;创建一个新的 Dockerfile3&#xff09;构建新的基础镜像3.注意事项4.commit命令踩坑记录1.背景 最近接手了一个docker服务&#xff0c;现需要对镜像进行修改&#xff0c;原始的 Dockerfile 已经丢失&#xff…...

食品与疾病关系预测赛题

和鲸平台数据分析实战 题目&#xff1a;食品与疾病关系预测算法赛道 一、赛题描述 食品与疾病关系预测算法赛道 越来越多的证据表明&#xff0c;食物分子与慢性疾病之间存在关联甚至治疗关系。营养成分可能直接或间接地作用于人类基因组&#xff0c;并调节参与疾病风险和疾病…...

Symbol

Symbol是ES6新增的一种基本数据类型 它用来表示独一无二的值&#xff0c; 通过Symbol函数生成 Symbol前面不能加new ,创建symbol类型指的时候传入一个参数&#xff0c;这个参数需要是字符串 使用Symbol函数创建一个symbol类型值&#xff0c;可以给它传入一个字符串参数&#xf…...

NC65 对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。

1、对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。 解决方案: 1、在期初余额节点,按Ctrl+ALT+A重建期初凭证; 2、到结账节点,重建余额表,选择有问题的财务核算账簿,注意:会计期间要放空; 3、到期初余额节点,将刚才删除期初数据的…...

位运算相关

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

Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号

首先区分一下Linux信号跟进程间通信中的信号量&#xff0c;它们的关系就犹如老婆跟老婆饼一样&#xff0c;没有一毛钱的关系。 信号的概念 信号的概念&#xff1a;信号是进程之间事件异步通知的一种方式&#xff0c;属于软中断。比如&#xff1a;红绿灯是一种信号&#xff0c…...

锯齿数组 - 贪心

文章目录锯齿数组 -贪心&#xff08;不过挺像滑动窗口的&#xff09;1144. 递减元素使数组呈锯齿状锯齿数组 -贪心&#xff08;不过挺像滑动窗口的&#xff09; 1144. 递减元素使数组呈锯齿状 题目链接&#xff1a;1144. 递减元素使数组呈锯齿状 题目大意&#xff1a;给你一个…...

[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种设计模式-工厂模式

工厂模式是一种创建型设计模式&#xff0c;它提供了一种创建对象的方式&#xff0c;而无需将具体的对象创建逻辑暴露给客户端。在Java中&#xff0c;工厂模式常常用于创建复杂对象或对象的构造过程涉及到多个步骤的情况。 在Android开发中&#xff0c;工厂模式也经常被使用&am…...

Linux操作系统学习(进程等待)

文章目录进程等待进程等待的必要性如何进程等待waiwaitpid验证进程等待 ​ 我们知道fork函数可以创建一个子进程&#xff0c;而子进程通常是替父进程完成一些任务&#xff0c;而父进程在fork之后需要通过wait/waitpid等待子进程退出。这就是进程等待 进程等待的必要性 通过获…...

Docker学习(十八)load 和 import 命令的区别

Docker 中有两个命令可以将本地文件系统中的 tar 文件导入到 Docker 中&#xff1a;docker load 和 docker import。尽管它们的作用类似&#xff0c;但它们之间有一些重要的区别。 1.使用方式的不同&#xff1a; docker load 的使用示例&#xff1a; docker load --input tes…...

mysql中的事务

在日常生活中,我们会遇到一个场景,那就是在转账的时候,A有1000块钱,要给B转账500,那么最后的结果是A有500,B有500,但是也有可能出现A没有钱了,B有1000块,或者在转账过程中卡顿,这是不符合逻辑的,那么这个时候就要使用事务来解决问题 事务就是把一堆sql语句打包成一个整体,要么…...

《C++ Primer Plus》第18章:探讨 C++ 新标准(9)

编程练习 下面是一个简短程序的一部分&#xff1a; int main() {using namespace std;// list of double deduced from list contentsauto q average_list ({15.4, 10.7, 9.0});cout << q << endl;// list of int deduced from list contentscout << averag…...

记录一次PWM信号异常问题

问题我使用单片机输出PWM控制机械臂&#xff0c;但是控制过程中&#xff0c;机械臂总是会出现莫名的抽动。利用示波器测试PWM信号&#xff0c;发现信号正常。过程&#xff08;1&#xff09;在反复的测试过程中&#xff0c;队友提出&#xff0c;将示波器的地线放在左侧的GND波形…...

简单了解---性能测试

目录 一、什么是性能测试 二、常见的性能测试指标 1、并发 2、响应时间 3、事务 4、点击率 5、吞吐量 6、资源利用率 三、性能测试的分类 1、一般测试 2、负载测试 3、压力测试 4、稳定性测试 四、为什么要做性能测试&#xff1f; 五、影响性能的因素有哪些&…...

1.机器学习笔记第一周

机器学习利用领域&#xff1a; 1&#xff1a;随着网络数据增大&#xff0c;需要搜集用户的数据&#xff0c;做喜好性偏向判断等。 2&#xff1a;只要有数据的&#xff0c;无论是医疗领域&#xff0c;还是基因领域都是需要机器学习来发现数据密码。 3&#xff1a;机器自我学习…...

若依学习(前后端分离版)——启动时发生了啥?(@PostConstruct)(mybatis log free)

我们可以发现若依启动时执行了一些sql我们可以安装一个插件mybatis log free 来更好的进行sql查看 &#xff0c;安装后需要修改一下若依的日志配置如下查看日志&#xff0c;我们发现执行了三个方法&#xff08;&#xff09;&#xff0c;分别查询了一些数据。以第二个方法为例子…...

每日十问9c++-内存模型和名称空间

每日十问9c内存模型和名称空间 1.对于下面的情况&#xff0c;应使用哪种存储方案? a.homer 是函数的形参。 b. secret变量由两个文件共享。 c.topsecret 变量由一个文件中的所有函数共享&#xff0c;但对于其他文件来说是隐藏的。 d. beencalled 记录包含它的函数被调用的次数…...

【python】JSON数据类型与Python数据类型之间的转化

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录JSON格式文件JSON格式序列化与反序列化作用JSON常用数据结构键值对的集合值的有序列表JSON数据类型与Python数据类型之间的转化JSON格式和python的区别读写json文件dump 把python 写到json文件load 把json写…...

Spring——什么是事务?传播行为?事务隔离级别有哪些?

思维导图一、什么是事务&#xff1f;多条DML要么同时成功&#xff0c;要么同时失败Transaction&#xff08;tx&#xff09;二、事务的四个过程&#xff1a;开启事务&#xff08;start transaction&#xff09;执行核心业务代码提交事务&#xff08;如果核心业务处理过程中没有出…...

【项目实战】使用Feign服务间相互调用,其实OpenFeign也没有想象中那么难嘛

一、Feign介绍 openfeign是一个java的http客户端,用来简化http调用 二、Feign架构(来自官方) Feign由五大部分组成, 由于刚开始接触 feign ,比较关注的 clients 跟 encoders/decoders 三、OKHTTP与Feign之间的关系 在Feign中,Client是一个非常重要的组件,Feign最终…...