UDP数据报套接字编程

目录

一、DatagramSocket API

1.1、DatagramSocket构造方法 

1.2、DatagramSocket方法 

二、DatagramPacket API

2.1、DatagramPacket构造方法

2.2、DatagramPacket方法

三、示例

实现字典查询器 


一、DatagramSocket API

DatagramSocket是UDP Socket,用于发送和接收UDP数据报针对服务器上启动的网络服务,对应到服务器上用来接收用户请求的进程。

1.1、DatagramSocket构造方法 

方法签名方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个端口(一般用于客户端)
DatagramSocket(int pot)创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端)

1.2、DatagramSocket方法 

方法签名方法说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacket p)从此套接字发送数据包(不会阻塞等待,直接发送)
void close()关闭此数据报套接字

网络编程在收发数据的过程中主要是对网卡进行操作。

  1. 接收数据,也就是对网卡进行读取。
  2. 发送数据,也就是对网卡进行写入。

 计算机中所有设备都是文件,那么网卡也被当作一个文件管理系统管理起来了,那么对网卡的写入和读取其实就是简单的对文件进行读取和写入的封装。

DatagramSocket其中部分功能就是对读取和写入的封装。对应的就是receive()和send()方法。

二、DatagramPacket API

DatagramPacket是UDP Socket,用于发送和接收的数据报针对通信的报文

2.1、DatagramPacket构造方法

方法签名方法说明
DatagramPacket(byte[] buf,int length)构造一个DatagramPacket以用来接收数据报,接受的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length)
DatagramPacket(byte[] buf,int offset,int length,SocketAddress address)构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二和第三个参数offset,length)。address指定目的主机的Ip和端口号

2.2、DatagramPacket方法

方法签名方法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接受的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端的端口号
byte[] getData()获取数据报中的数据

三、示例

实现字典查询器 

  1. 客户端先接收键盘输入,表示要查找的字符。
  2. 发送请求:用户输入的数据打包成DatagramPacket,作为数据报发送到服务端 。
  3. 服务端接收并处理请求:接收请求数据,根据该请求数据来计算响应。
  4. 服务端返回响应:使用DatagramPacket来封装相应数据,作为响应的数据报,返回给客户端。
  5. 客户端接收响应:简单的打印输出所有的响应内容。

1、定义字典类,将我们要查找的词导入到字典类中


import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;/*** 基于UDP的字典查询器*/
public class UDPDictServer extends UDPEchoServer {Map<String,String> map;public UDPDictServer(int port) throws SocketException {super(port);map=new HashMap<>();map.put("狗","dog");map.put("猫","cat");map.put("老鼠","mouse");map.put("蛇","snake");map.put("鸡","蔡徐坤");map.put("鸭子","duck");map.put("三万", "土鸡");map.put("小寄","dog");}@Overrideprotected String process(String request) {return map.getOrDefault(request, "查无此词");}public static void main(String[] args) throws IOException {//初始化字典服务器UDPDictServer server=new UDPDictServer(11111);server.start();}
}

2、实现UDP服务端


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;/*** 基于UDP的服务端*/
public class UDPEchoServer {//声明一个可以提供UDP协议的对象private DatagramSocket socket;//通过构造方法来指定服务的端口号public UDPEchoServer(int port) throws SocketException {//校验端口号if(port<1||port>65535){throw new RuntimeException("端口号应在1025~65535之间");}//实现UDP服务this.socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动...");//循环处理请求while(true){//1、使用DatagramPacket接收用户的请求DatagramPacket requestPacket=new DatagramPacket(new byte[1024],1024);//2、接收数据socket.receive(requestPacket);//3、解析接收的数据String request=new String(requestPacket.getData(),0,requestPacket.getLength());//4、根据请求来计算响应String response=process(request);//5、使用DatagramPacket来封装相应数据DatagramPacket responsePacket=new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),response.getBytes().length,requestPacket.getSocketAddress());//6、发送响应socket.send(responsePacket);//7、打印日志System.out.printf("[%s :%d] request=%s,response=%s\n", requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}protected String process(String request) {return request;}public static void main(String[] args) throws IOException {UDPEchoServer server=new UDPDictServer(11111);server.start();}
}

3、实现UDP客户端

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** 基于UDP的客户端*/
public class UDPEchoClient {//声明一个Socket对象private DatagramSocket socket;private String serverIp;private int serverPort;//通过构造方法初始化socket,指定端口地址,ippublic UDPEchoClient(String serverIp, int serverPort) throws SocketException {this.socket=new DatagramSocket();this.serverIp = serverIp;this.serverPort = serverPort;}//启动客户端服务public void start() throws IOException {System.out.println("客户端已启动...");//循环处理客户端输入while(true){System.out.println("->");//定义ScannerScanner sc=new Scanner(System.in);//1、获取用户的输入String request=sc.nextLine();if(request==null||request.equals("")){System.out.println("您输入了一个空数据!!!");continue;}//2、用户输入的数据打包成DatagramPacket//3、创建SocketAddress对象,表示服务器的IP和端口号SocketAddress address=new InetSocketAddress(serverIp, serverPort);DatagramPacket requestPacket=new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),request.getBytes().length,address);//4、发送数据到服务器socket.send(requestPacket);//5、接收服务器的响应DatagramPacket responsePacket=new DatagramPacket(new byte[1024],1024);socket.receive(responsePacket);//6、解析得到的响应数据String response=new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");//7、打印响应日子System.out.printf("request=%s,response=%s.\n",request,response);}}public static void main(String[] args) throws IOException {//初始化客户端服务,客户端口号和服务端口号要保持一致,不然就会访问不到UDPEchoClient client=new UDPEchoClient("127.0.0.1", 11111);client.start();}
}

运行结果:

 

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

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

相关文章

⌈C++⌋深度剖析构造、拷贝构造与赋值运算符重载——深浅拷贝、explicit、类型转换等

目录 一、认识拷贝构造函数 1、什么是拷贝构造 2、深拷贝与浅拷贝 3、编译器可以绕过拷贝构造函数&#xff08;C Primer P442&#xff09; 4、explicit修饰 二、认识赋值运算符重载 1、赋值运算符重载格式 2、默认赋值运算符重载 3、赋值运算符都必须定义为成员函数 …

【简单认识LVS+Keepalived负载均衡高可用群集】

文章目录 一、Keepalived高可用详解1、简介2、原理3、Keepalived体系主要模块及其作用&#xff1a; 二、LVSKeepalived 高可用群集部署实例1.配置NFS共享存储器2.配置节点web服务&#xff08;两台的配置相同&#xff09;&#xff08;1&#xff09;配置虚拟 IP 地址&#xff08;…

Java中Map中10w条数据用什么循环性能最好呢?

加油&#xff0c;新时代打工人&#xff01; 1、java中List集合三种获取集合元素方式 2、Java中Map使用增强for循环和迭代器获取key和value 选择合适的循环方式&#xff0c;让性能最优&#xff01; public class Test2 {public static void main(String[] args) {//初始化 10w…

如何获取铁粉

忽然发现我的铁粉从100变成了540&#xff0c;分享下我的经验&#xff0c;我觉得可能是我的机器人经常互动的问题&#xff0c;结合自己的看法和平台大佬的想法一些进行了梳理&#xff1a; 在当今社交媒体时代&#xff0c;吸引和保留铁粉&#xff08;忠实粉丝&#xff09;对于个…

面试题更新之-DOCTYPE html相关问题

文章目录 <!DOCTYPE html>是什么&#xff1f;为什么要在html文件开头加上一个<!DOCTYPE html>DOCTYPE的作用&#xff0c;严格与混杂模式的区别&#xff0c;有何意义HTML5为什么只需要写<!DOCTYPE HTML> 是什么&#xff1f; 是HTML文档的文档类型声明&#xf…

实战攻防之积极防御体系建设 | 中睿天下受邀参与诸子云沙龙

7月8日&#xff0c;中睿天下受邀参与由诸子云举办的“网络与数据安全”主题沙龙&#xff0c;中睿天下技术经理徐丹丹就《实战攻防之积极防御体系建设》这一主题进行了分享交流。 本次沙龙由南京分会会长宋士明主持&#xff0c;活动邀请到BASF、江苏省联社、华泰证券、宁证期货、…

【kubernetes系列】Kubernetes之ServiceAccount

概述 Service Account是什么呢&#xff0c;顾名思义&#xff0c;服务账号&#xff0c;一种给服务使用的账号&#xff0c;它不是给Kubernetes的集群的用户&#xff08;系统管理员、运维人员、租户用户等&#xff09;使用&#xff0c;而是给运行在Pod里的进程用的&#xff0c;它…

flink启动报错Failed to construct kafka producer

flink local模式下启动 sink2kafka报错&#xff0c;具体报错如下 apache.kafka.common.KafkaException: Failed to construct kafka producerat org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:432)at org.apache.kafka.clients.producer.…

wps如何加载mathtype和Endnote

为了支持国产化软件&#xff0c;弃用office套装&#xff0c;现在改用wps办公软件&#xff0c;但是写作科技论文的时候还是会出现很多的不方便&#xff0c;比如文献引用、公式排版编号等等。尽管wps自带了公式编辑器&#xff0c;然鹅这可太不方便了&#xff0c;因此把几个技巧总…

谈谈你对 binder 的理解?

面试官提了一个问题&#xff0c;我们来看看 &#x1f60e;、&#x1f628; 和 &#x1f914;️ 三位同学的表现如何吧 &#x1f60e; 自认为无所不知&#xff0c;水平已达应用开发天花板&#xff0c;目前月薪 10k 面试官️&#xff1a;谈谈你对 binder 的理解 &#x1f60e;&a…

驱动开发-day10

驱动代码&#xff1a; #include <linux/cdev.h> #include <linux/device.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/mod_devicetable.h> #include …

本地服务器localhost:3000一直连接不上

1.检查使用端口3000的进程: 在Windows上,运行 netstat -ano | findstr :3000在Mac/Linux上,运行lsof -i :3000 这将列出当前使用端口3000的任何进程。您要终止这些进程以释放该端口。 2.检查防火墙规则: 确保您的防火墙允许连接到localhost:3000。在MacOS和Windows上,通常不…