首页 > 编程语言 >Java登陆第十三天——网络编程(三)DatagramSocket

Java登陆第十三天——网络编程(三)DatagramSocket

时间:2023-11-24 18:44:41浏览次数:46  
标签:DatagramSocket datagramSocket DatagramPacket Java 端口 9999 new 第十三天

DatagramSocket

使用DatagramSocket(数据套接字)可以进行UDP程序的开发,此类可以建立单向地、不可靠地、快速地通信。

在UDP编程中,混淆了服务端和客户端的概念。因为通信是单向的,所以身份可以随时切换。

(也有人把TCP称作服务端客户端,UDP称作发送端和接收端)

DatagramSocket类常用方法如下:

方法 类型 描述
public DatagramSocket(int port) throws SocketException 构造方法 监听指定端口
public void send(DatagramPacket p) throws IOException 普通方法 发送数据报
public synchronized void receive(DatagramPacket p) throws IOException 同步方法 等待客户端请求并接收数据报(没有会一直阻塞)

image

DatagramPacket

在Java中,使用DatagramPacket类操作数据报。

常用方法如下:

方法 类型 描述
public DatagramPacket(byte buf[], int length) 构造方法 构建数据报的数据、数据长度
public DatagramPacket(byte buf[], int length, InetAddress address, int port) 构造方法 构建数据报的数据、数据长度、目标地址和端口
public synchronized byte[] getData() 同步方法 拆开数据报,获取数据
public synchronized int getLength() 普通方法 获取数据长度

栗子:编写一个本机的接收端,端口为9999

接收端,Test25receive类:

//接收端,Test25receive类
    public static void main(String[] args) {
        try {
            DatagramSocket datagramSocket = new DatagramSocket(9999);
            byte[] bytes = new byte[1024];//创建容器,留作数据
            System.out.println("成功创建容器,监听9999端口");
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
            datagramSocket.receive(datagramPacket);
            //若无客户端访问9999端口,程序就会阻塞在此;若有客户端访问9999端口,程序继续向下执行。

            System.out.println("1");//若执行到此证明不会阻塞
            datagramSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

程序运行结果:

成功创建容器,监听9999端口
//阻塞中....

栗子:发送端给本机9999端口的接收端发送hello,world!

发送端,Test25send类:

//发送端,Test25send类
public class Test25send {
    public static void main(String[] args) {
        try {
            DatagramSocket datagramSocket = new DatagramSocket();//因为接收端不打算回消息,所以不监听端口
            byte[] bytes = "hello,world!".getBytes();
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"),9999);
            //构建一个数据报,其目的地址是本机的9999端口。
            datagramSocket.send(datagramPacket);
            System.out.println("成功发送数据报");

            datagramSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接收端,Test25receive类:

//接收端,Test25receive类
public class Test25receive {
    public static void main(String[] args) {
        try {
            DatagramSocket datagramSocket = new DatagramSocket(9999);
            byte[] bytes = new byte[1024];//创建容器,留作数据
            System.out.println("成功创建容器,监听9999端口");
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
            datagramSocket.receive(datagramPacket);
            //若无发送端访问9999端口,程序就会阻塞在此;若有发送端访问9999端口,程序继续向下执行。
            byte[] data = datagramPacket.getData();//拆包后的数据
            System.out.println(new String(data,0, datagramPacket.length));//长度一定是数据报获取的长度,否则带有bytes后的很多00000

            System.out.println("1");//若执行到此证明不会阻塞
            datagramSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

先运行接收端,再运行发送端,程序运行结果:
image

栗子:发送端发送信息"四大名著是哪些?"
接收端接收问题后回复""四大名著有。。。。
否则回复what?

客户端,Test25send类:

//客户端,Test25send类
public class Test25send {
    public static void main(String[] args) {
        try {
            DatagramSocket datagramSocket = new DatagramSocket(9988);//因为接收端要回消息,监听端口9988
            byte[] bytes = "四大名著11哪些?".getBytes();
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"),9999);
            //构建数据报,其目的地址是本机的9999端口。
            datagramSocket.send(datagramPacket);
            System.out.println("成功发送数据报");

            //构建数据报,其目的地址是本机的9999端口。
            byte[] b = new byte[1024];
            DatagramPacket datagramPacket2 = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"),9999);
            datagramSocket.receive(datagramPacket2);
            System.out.println(new String(datagramPacket2.getData(),0, datagramPacket2.getLength()));
            datagramSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端,Test25receive类:

//服务端,Test25receive类
public class Test25receive {
    public static void main(String[] args) {
        try {
            DatagramSocket datagramSocket = new DatagramSocket(9999);
            byte[] bytes = new byte[1024];//创建容器,留作数据
            System.out.println("成功创建容器,监听9999端口");
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
            datagramSocket.receive(datagramPacket);
            //若无客户端访问9999端口,程序就会阻塞在此;若有客户端访问9999端口,程序继续向下执行。
            String s = new String(datagramPacket.getData(), 0, datagramPacket.getLength());//拆包后的数据

            DatagramPacket datagramPacket2;
            byte[] b;
            if("四大名著是哪些?".equals(s)) {
                b = "四大名著有。。。。".getBytes();
            } else {
                b = "what?".getBytes();
            }
            datagramPacket2 = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"), 9988);
            datagramSocket.send(datagramPacket2);


            datagramSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

程序运行结果:
image

标签:DatagramSocket,datagramSocket,DatagramPacket,Java,端口,9999,new,第十三天
From: https://www.cnblogs.com/Ocraft/p/17854507.html

相关文章

  • java多线程学习之路-不能理解
    1importjava.util.concurrent.CountDownLatch;23/**4*颠覆理解的,为什么不会出问题,执行多次,结果都是正确,并且一致5*/6classMyData{7inta=5;//可预定总座位数8intb=0;//已预定座位数910publicvoidyd(){11if(b<......
  • Java Web实现文件下载的几种方式
    文件下载可以说是网站的基础功能,要实现最下载功能,有一种最基本的方法,那就是将超链接的href属性指向对应的资源文件。如下面连接指向了百度首页的图片:​ ​I'mtheindexofBaidu​​但这种方式的缺陷也是很明显的,目录信息被获取,不利于信息安全。其实信息安全还是其次,主要还是......
  • JAVA进阶 —— 方法引用
    原文链接:https://blog.csdn.net/hdakj22/article/details/129453599一、内容概述方法引用可以拆分为方法和引用两方面:方法引用:把已经有的方法拿过来用,当作函数接口中抽象方法的方法体。::(方法引用符)但是要注意:并不是所有的方法都可以直接引用,需要满足以下四种条件引用......
  • JavaScript数组中的常用函数解析
    1.splice方法当使用splice()方法时,可以传递不同的参数来实现不同的操作。以下是splice()方法的参数说明:array.splice(start,deleteCount,item1,item2,...);start:必需,指定要进行操作的起始索引位置。如果该值为负数,则表示从数组末尾开始计算的偏移量。例如,-1表示倒数第......
  • java 关于 Finalizer 过多导致内存(Res)缓慢上涨
     病因:事情的起因是由Flume的项目采集问题引发的.测试人员发现用top命令查看采集进程的Res一直不断上涨姿势.所以怀疑是内存泄漏.  一,对症下药首先,第一步肯定是先瞅瞅代码,看看有没有那些资源啥的没关闭,正如读者所想----没有发现.二,通过辅助工具最......
  • 这篇保证你彻底搞懂Java NIO的Selector事件选择器
     Selector提供选择执行已经就绪的任务的能力,使得多元I/O成为可能,就绪选择和多元执行使得单线程能够有效率地同时管理多个I/Ochannel。C/C++许多年前就已经有select()和poll()这两个POSIX(可移植性操作系统接口)系统调用可供使用。许多os也提供相似的功能,但对Java程序......
  • Java实验报告五
    实验五实验名称:文件与I/O流实验目的:掌握文件与输入输出流的使用。实验时间:(2学时)实验类型:验证型实验内容:1.创建类:FindFile.java,遍历当前目录,打印目录中文件名称,目录打印”isDirectory”,文件打印“isfile”。修改程序打印当前目录及子目录信息。提示:当前目录名用......
  • JavaWeb中的文件的上传和下载
    文件上传1.要有一个form标签,method=post请求2.form标签的encType属性的值必须为multipart/form-data值3.在from标签中使用inputtype=file添加上传的文件4.编写服务器代码接收上传的数据Content-Type:表示提交的数据类型enctype="multipart/form-data":表示提交的数据,以多段(每......
  • Java线程生命周期
    操作系统线程生命周期操作系统线程生命状态有5种。初始状态(New)进程正在被创建时的状态。仅为线程对象开辟了一块堆内存,实际上线程在操作系统层面还未创建。就绪状态(Ready)可运行,由于其他进程处于运行状态而暂时停止运行运行状态(Running)该进程此时正占用CPU......
  • Java实验报告
    实验一实验名称:JAVA中循环结构实验目的:熟悉循环结构,熟悉JAVA类的定义以及参数的传递。实验时间:(2学时)实验类型:验证型实验内容:(1)金字塔:Pyramid.java在屏幕上显示一个由星型符号“*”组成的金字塔图案,要求用户设置金字塔的高度,程序能根据用户设置的高度打印金字塔,......