Java网络通信UDP

news2024/9/29 11:36:38

目录

网络通信基础

UDP通信

服务器

1.想要使用UDP通信 要先打开DatagramSocket文件 端口号可以手动指定或系统随机分配

2.阻塞等待接收客户端数据;创建DatagramPacket接收客户端传来的数据

3.处理客户端传来的数据,并进行业务处理(这里只演示UDP通信 所以只是回传数据)

4.处理数据成DatagramPacket并发送数据给客户端

整体代码

客户端

1.创建DatagramSocket (这里客户端端口号系统分配即可,不允许和服务器同一端口号)

2.客户端接收用户的数据

3.处理用户数据成DatagramPacket 指定要发送服务器的地址与端口号

4.发送数据给客户端

5.阻塞等待服务器响应

6.处理服务器响应的数据

7.显示数据给用户

整体代码

继承服务器代码,重写业务代码即可


网络通信基础

  1. 物理层:网络通信的基础设施                                    运快递的公路
  2. 数据链路层:两个相邻的节点之间如何传输               两个集散点之间的传输
  3. 网络层:两个点之间的路径规划                                 物流公司规划快递的路径
  4. 传输层:两个点之间的通信(不考虑路径规划)        卖家发货 只考虑起点和终点
  5. 应用层:数据传输过去之后 如何使用                         快递拿到之后如何使用

网络编程的主要工作写应用层的代码,处理应用层的协议数据

从5->1往下传输 每次传输都会依次添加报头 称为封装    QQ1发送

从1->5往上传输 每次传输都会解析去掉报头                   QQ2接收

传输层提供两种协议

TCP:有连接,可靠传输,面向字节流,全双工

UDP:无连接,不可靠传输,面向数据包,半双工

可靠传输:数据对方有没有接收到,发送方有感知;打电话就是可靠的,可以知道对方有没有听到。

不可靠传输:数据对方有没有接收到,不管,也不知道;微信就是不可靠,不知道对方有没有看到我的消息。

全双工:双向通信 可以A->B B->A 同时进行

半双工:单向通信 A->B或者B->A 同时只允许一个进行

程序要进行网络通信,需要一个端口号(客户端与服务器的端口号不能相同!)

端口号相当于用来在网络上区分进行的身份标识符

分配端口号有 1.手动指定 2.系统自动分配

UDP通信

UDP的Socket API

DatagramSocket和DatagramPaclet 核心类

socket类本质相当于文件 构造一个DatagramSock对象,相当于打开了一个内核中的socket文件

打开后就可以传输数据了

传输数据已 DatagramPacket为基本单位

InetSocketAddress类 IP地址+端口号

send发送数据 receive接收数据 close关闭数据

DatagramOacket 表示一个UDP数据报 UDP是面向数据报的协议

服务器

1.想要使用UDP通信 要先打开DatagramSocket文件 端口号可以手动指定或系统随机分配

    //想要使用UDP服务器 要打开一个文件
    private DatagramSocket socket=null;

    //创建对象
    //服务器IP和端口号是提供给客户端 方便客户端知道地址发送过来
    public Test1(int port) throws SocketException {
        socket=new DatagramSocket(port);//创建实例  绑定进程端口号

2.阻塞等待接收客户端数据;创建DatagramPacket接收客户端传来的数据

            DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);
            //客户端发来的请求放到参数datagramPacket  输出性参数
            System.out.println("我正在等待!");
            socket.receive(datagramPacket);//阻塞等待 客户端发起请求
            System.out.println("服务器接收到数据");

3.处理客户端传来的数据,并进行业务处理(这里只演示UDP通信 所以只是回传数据)

//把传来的数据构造成数据 1.获取数据 从0开始构造 构造到数据结尾
            String request=new String(datagramPacket.getData(),0,datagramPacket.getLength());
            System.out.println("接收到的数据:"+request);
            //处理业务
            String requst=process(request);
            System.out.println("服务器处理数据");

 public String process(String s){
        return s;
    }

4.处理数据成DatagramPacket并发送数据给客户端

//要传回客户端也要把数据构造成DatagramPacket
            //把string构造到byte字节  1.字节数据,2.字节长度 3.客户端的id+客户端的端口号
            DatagramPacket datagramPackets=new DatagramPacket(request.getBytes(),request.getBytes().length,datagramPacket.getSocketAddress());
            //发送数据
            socket.send(datagramPackets);
            System.out.println("服务器发送数据成功");
            System.out.printf("[地址:%s:端口号:%d] 发来数据:%s 服务器响应数据:%s\n",datagramPacket.getAddress().toString(),datagramPacket.getPort(),request,requst);

整体代码

package DemoUDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

//服务端
public class Test1 {
    //想要使用UDP服务器 要打开一个文件
    private DatagramSocket socket=null;

    //创建对象
    //服务器IP和端口号是提供给客户端 方便客户端知道地址发送过来
    public Test1(int port) throws SocketException {
        socket=new DatagramSocket(port);//创建实例  绑定进程端口号
    }

    public void start() throws IOException {
        System.out.println("启动服务器");
        while (true){
            //创建一个DatagramPacket(创建缓存区,缓存区长度)用来接收客户端发来的请求
            DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);
            //客户端发来的请求放到参数datagramPacket  输出性参数
            System.out.println("我正在等待!");
            socket.receive(datagramPacket);//阻塞等待 客户端发起请求
            System.out.println("服务器接收到数据");
            //把传来的数据构造成数据 1.获取数据 从0开始构造 构造到数据结尾
            String request=new String(datagramPacket.getData(),0,datagramPacket.getLength());
            System.out.println("接收到的数据:"+request);
            //处理业务
            String requst=process(request);
            System.out.println("服务器处理数据");

            //要传回客户端也要把数据构造成DatagramPacket
            //把string构造到byte字节  1.字节数据,2.字节长度 3.客户端的id+客户端的端口号
            DatagramPacket datagramPackets=new DatagramPacket(request.getBytes(),request.getBytes().length,datagramPacket.getSocketAddress());
            //发送数据
            socket.send(datagramPackets);
            System.out.println("服务器发送数据成功");
            System.out.printf("[地址:%s:端口号:%d] 发来数据:%s 服务器响应数据:%s\n",datagramPacket.getAddress().toString(),datagramPacket.getPort(),request,requst);
        }
    }
    public String process(String s){
        return s;
    }

    public static void main(String[] args) throws IOException {
        //端口号范围 0--65535 1024以下的端口是系统用的  尽量用1024以上 65535以下
        Test1 test1=new Test1(8080);
        test1.start();
    }
}

客户端

1.创建DatagramSocket (这里客户端端口号系统分配即可,不允许和服务器同一端口号)

DatagramSocket Socket=null;

    //客户端端口号需要系统自动分配 不能指定与服务器端口号一样,不然会抢占服务器端口号 导致后启动的一端无法启动
    public Test2() throws SocketException {
        Socket=new DatagramSocket();
    }

2.客户端接收用户的数据

Scanner scanner=new Scanner(System.in);
            System.out.println("客户端输入数据:>");
            String Data=scanner.nextLine();

3.处理用户数据成DatagramPacket 指定要发送服务器的地址与端口号

//处理用户数据
            //1.把string类型处理成byte字节数据 datagramPacket类型 里面附带发送地址和发送对方的端口号
            DatagramPacket datagramPacket=new DatagramPacket(Data.getBytes(),Data.getBytes().length, InetAddress.getByName("127.0.0.1"),8080);
            System.out.println("客户端处理数据");

4.发送数据给客户端

 //发送数据
            Socket.send(datagramPacket);
            System.out.println("客户端发送数据");

5.阻塞等待服务器响应

//阻塞等待服务器的响应数据
            DatagramPacket datagramPackets=new DatagramPacket(new byte[1024],1024);
            Socket.receive(datagramPackets);
            System.out.println("客户端接收服务器响应数据");

6.处理服务器响应的数据

//处理服务器响应的数据
            String Datas=new String(datagramPackets.getData(),0,datagramPackets.getLength());
            System.out.println("客户端处理数据");

7.显示数据给用户

System.out.printf("服务器响应数据:%s\n",Datas);

整体代码

package DemoUDP;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

//客户端
public class Test2 {
    DatagramSocket Socket=null;

    //客户端端口号需要系统自动分配 不能指定与服务器端口号一样,不然会抢占服务器端口号 导致后启动的一端无法启动
    public Test2() throws SocketException {
        Socket=new DatagramSocket();
    }

    public void start() throws IOException {
        while (true){
            //接收用户数据
            Scanner scanner=new Scanner(System.in);
            System.out.println("客户端输入数据:>");
            String Data=scanner.nextLine();

            //处理用户数据
            //1.把string类型处理成byte字节数据 datagramPacket类型 里面附带发送地址和发送对方的端口号
            DatagramPacket datagramPacket=new DatagramPacket(Data.getBytes(),Data.getBytes().length, InetAddress.getByName("127.0.0.1"),8080);
            System.out.println("客户端处理数据");

            //发送数据
            Socket.send(datagramPacket);
            System.out.println("客户端发送数据");

            //阻塞等待服务器的响应数据
            DatagramPacket datagramPackets=new DatagramPacket(new byte[1024],1024);
            Socket.receive(datagramPackets);
            System.out.println("客户端接收服务器响应数据");

            //处理服务器响应的数据
            String Datas=new String(datagramPackets.getData(),0,datagramPackets.getLength());
            System.out.println("客户端处理数据");

            //显示处理后的数据给用户
            System.out.printf("服务器响应数据:%s\n",Datas);
        }
    }

    public static void main(String[] args) throws IOException {
        Test2 test2=new Test2();
        test2.start();
    }
}

继承服务器代码,重写业务代码即可

package DemoUDP;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

public class Test3 extends Test1{

    public Test3(int port) throws SocketException {
        super(port);
    }

    @Override
    public String process(String s) {
        Map<String,String> dic=new HashMap<String,String>();

        dic.put("cat","猫");

        return dic.getOrDefault(s,"此单词还未更新");
    }

    public static void main(String[] args) throws IOException {
        Test3 test3=new Test3(8080);
        test3.start();
    }


}

指定客户端多开

之后就可以同时运行多个客户端访问服务器

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

雷电将军部分技能AOE范围测试

简单说一下&#xff0c;以往的AOE范围数据大部分来自Dim提供的拆包文件或泄露的GM端控制台显示的距离数据&#xff0c;如《AOE范围学》中的数据&#xff0c;然而米哈游自1.6版本及以后未再公开泄露过GM端&#xff0c;因为一些原因Dim也没再更新拆包文件中角色技能参数相关的部分…

二路归并排序的算法设计和复杂度分析and周记

数据结构实验报告 实验目的: 通过本次实验&#xff0c;了解算法复杂度的分析方法&#xff0c;掌握递归算法时间复杂度的递推计算过程。 实验内容&#xff1a; 二路归并排序的算法设计和复杂度分析 实验过程&#xff1a; 1.算法设计 第一步&#xff0c;首先要将数组进行…

Vue3快速上手(十五)Vue3路由器使用和简单路由切换

一、路由的概念 1.1 路由及路由器 路由器&#xff1a;通常指的是我们家里上网用的路由器&#xff0c;通过网络接口&#xff0c;一根网线&#xff0c;链接至电脑&#xff0c;一般我们的电脑就可以上网了&#xff0c;多个网络接口&#xff0c;链接多个电脑&#xff0c;形成一组…

图神经网络实战——图论基础

图神经网络实战——图论基础 0. 前言1. 图属性1.1 有向图和无向图1.2 加权图和非加权图1.3 连通图和非连通图1.4 其它图类型 2. 图概念2.1 基本对象2.2 图的度量指标2.2 邻接矩阵表示法 3. 图算法3.1 广度优先搜索3.2 深度优先搜索 小结系列链接 0. 前言 图论 (Graph theory) …

springboot-基础-eclipse集成mybatis+使用方法+排错

备份笔记。所有代码都是2019年测试通过的&#xff0c;如有问题请自行搜索解决&#xff01; 目录 集成mybatis安装mybatis的jar包安装插件&#xff1a;mybatis-generator安装方法生成方法报错&#xff1a;java.lang.RuntimeException: Exception getting JDBC Driver mybatis注解…

深入了解Kafka的文件存储原理

Kafka简介 Kafka最初由Linkedin公司开发的分布式、分区的、多副本的、多订阅者的消息系统。它提供了类似于JMS的特性&#xff0c;但是在设计实现上完全不同&#xff0c;此外它并不是JMS规范的实现。kafka对消息保存是根据Topic进行归类&#xff0c;发送消息者称为Producer&…

【鸿蒙开发】第十五章 ArkTS基础类库-并发

1 简述 并发是指在同一时间段内&#xff0c;能够处理多个任务的能力。为了提升应用的响应速度与帧率&#xff0c;以及防止耗时任务对主线程的干扰&#xff0c;OpenHarmony系统提供了异步并发和多线程并发两种处理策略&#xff0c;ArkTS支持异步并发和多线程并发。并发能力在多…

部署bpmn项目实现activiti流程图的在线绘制

本教程基于centos7.6环境中完成 github开源项目: https://github.com/Yiuman/bpmn-vue-activiti软件&#xff1a;git、docker 1. 下载源代码 git clone https://github.com/Yiuman/bpmn-vue-activiti.git2. 修改Dockerfile文件 声明基础镜像&#xff0c;将项目打包&#xff…

LeetCode---386周赛

题目列表 3046. 分割数组 3047. 求交集区域内的最大正方形面积 3048. 标记所有下标的最早秒数 I 3049. 标记所有下标的最早秒数 II 一、分割数组 这题简单的思维题&#xff0c;要想将数组分为两个数组&#xff0c;且分出的两个数组中数字不会重复&#xff0c;很显然一个数…

AI又进化了

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 一直想做但没做的板块&#xff0c;整理一段时间内AI领域的前沿动态&#xff08;符合大多粉丝研究领域/感兴趣方向&#xff09;&#xff0c;了解了解外面世界发展成啥样了&#xff0c;一起看看吧~ 谷歌…

网关kong记录接口处理请求和响应插件 tcp-log-with-body的安装

tcp-log-with-body 介绍 Kong的tcp-log-with-body插件是一个高效的工具&#xff0c;它能够转发Kong处理的请求和响应。这个插件非常适用于需要详细记录API请求和响应信息的情景&#xff0c;尤其是在调试和排查问题时。 软件环境说明 kong version 2.1.4 - 2.8.3 [可用亲测]C…

8、Redis-Jedis、Lettuce和一个Demo

目录 一、Jedis 二、Lettuce 三、一个Demo Java集成Redis主要有3个方案&#xff1a;Jedis、Lettuce和Redisson。 其中&#xff0c;Jedis、Lettuce侧重于单例Redis&#xff0c;而Redisson侧重于分布式服务。 项目资源在文末 一、Jedis 1、创建SpringBoot项目 2、引入依赖 …

【PDF技巧】网上下载的pdf文件怎么才能编辑

不知道大家有没有遇到过网上下载的PDF文件不能编辑的情况&#xff0c;今天我们来详细了解一下导致无法编辑的原因即解决方法有哪些。 第一种原因&#xff1a;PDF文件中的内容是否是图片&#xff0c;如果确认是图片文件&#xff0c;那么我们想要编辑&#xff0c;就可以先使用PD…

《Improving Calibration for Long-Tailed Recognition》阅读笔记

论文标题 《Improving Calibration for Long-Tailed Recognition》 改进长尾识别的校准工作 作者 Zhisheng Zhong、 Jiequan Cui、Shu Liu 和 Jiaya Jia 香港中文大学和 SmartMore 初读 摘要 深度神经网络在训练数据集类别极度不平衡时可能会表现不佳。最近&#xff0c…

高中数学:函数的单调性

一、概念 二、单调区间的表示方法 注意 1、两个不相连的部分&#xff0c;单调性相同&#xff0c;则两个单调区间用逗号隔开&#xff0c;不能用∪号连接。 2、单调区间端点都用开区间表示&#xff0c;最安全。 三、常见题型 1、普通简单函数单调性判断 解题思路&#xff1a;画…

VueCli的安装与卸载

文章目录 一.Node安装包的报读网盘提取码二、Vue脚手架Cli三、Vue-CLI使用步骤(自定义安装)1.转换路径并创建项目2.创建步骤的解释(保姆级)3.等待vue项目自己创建好(保姆级) 四、通过npm对vue的安装与卸载 一.Node安装包的报读网盘提取码 下面的链接为地址: Node的百度网盘提取…

【操作系统(Operator System)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、概念 二、结构示意图 三、尝试理解操作系统 系统调用和库函数概念 承上启下 总结 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升起的太阳&#xff…

每日下载超1000万次,这个前端工具太有用了!

今天来分享一个前端必备的工具&#xff0c;其每天在 npm 上的下载量高达 1000 万次&#xff0c;几乎每个前端项目都在用&#xff0c;它就是 PostCSS。这款工具已经成为前端开发领域中不可或缺的一部分&#xff0c;之所以如此受欢迎&#xff0c;不仅是因为它能够帮助开发者自动化…

双周回顾#007 - 前端与后端

前端的问题不是难&#xff0c;而是它面对最终用户。只要用户的喜好和口味发生变化&#xff0c;前端就必须跟上。 这导致前端不得不快速变化&#xff0c;因为用户的口味正在越来越快地改变。 后端不需要面对最终用户&#xff0c;需要解决的都是一些经典的计算机科学问题&#…

智能的花火,照亮一座5G钢铁工厂的时代之舞

“东风夜放花千树。更吹落&#xff0c;星如雨。凤箫声动&#xff0c;玉壶光转&#xff0c;一夜鱼龙舞”&#xff0c;辛弃疾在《青玉案》中描绘的“打铁花”&#xff0c;是刚刚过去的春节假期中&#xff0c;全国各地都在上演的中式浪漫。 当铁水被击打向高空&#xff0c;犹如千万…