[网络编程]UDP协议,基于UDP协议的回显服务器

目录

1.UDP协议介绍

2.UDP协议在Java中的类

2.1DatagramSocket类

2.2DatagramPacket

3.回显服务器

3.1Sever端 

3.2Client端

1.UDP协议介绍

  UDP协议是一种网络协议,它是无连接的,全双工,并且是面向数据报,不可靠的一种协议。常用于在线视频播放,游戏这种实时性要求比较高的应用。或者无需可靠传输的应用,如DNS查询 SNMP等。一次UDP数据报报文传输的数据最大为64kb,实际上,UDP因为头部占用八个字节。所以可传输的精准大小为64kb-8b = 65507字节。

2.UDP协议在Java中的类

 UDP协议作为传输层协议,在Java中我们无需面对原生UDP协议,我们只需要调用Java封装好的类来使用UDP协议来传输和接受数据即可。在Java中有两个类,分别是DatagramSocket类和DatagramPacket类。

2.1DatagramSocket类

DatagramSocket用于创建Socket,绑定到端口号。它将网卡抽象成文件来方便程序猿来来操作。

DatagramSocket类的构造方法:
DatagramSocket类里的方法:

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

2.2DatagramPacket

DatagramPacket是UDP Socket发送和接收的数据报

DatagramPacket的构造方法:

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

DatagramPacket的方法:

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

3.回显服务器

为了方便大家理解和更好的使用UDP协议中的这两个类来实现网络编程,跨主机通信。

我们来写个简单的客户端-服务器程序-回显服务器,客户端将数据发送到服务器上,服务器在返回给客户端这个数据并且打印下来。主要目的是为了方便大家理解。

3.1Sever端 

在Sever端写之前,我们先讲明白几件事,首先就是我们的构造方法要不要指定端口号。答案是肯定的,因为这是服务器端,客户端想要访问它,肯定要有一个固定的地址,不然如何去访问,所以在构造方法中,我们直接从1024-65535这些端口号中选择一个给绑定上。

还有就是我们的主要逻辑过程:

1.接受数据并解析

2.将这个数据进行服务器的操作,即根据请求计算响应。

3.将响应返回给客户端。

明白了这些以后,我们开始编写代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class UdpEchoSever {DatagramSocket socket = null;public UdpEchoSever (int sort) throws SocketException {socket = new DatagramSocket(sort);//因为是服务器程序,所以我们要指定端口号}public void start() throws IOException {while (true){ //这里的while(true)是因为会有很多客户端来访问这个服务器,所以我们的服务器是7*24小时运行的System.out.println("服务器启动");byte[] bytes = new byte[1024];DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length); //创建一个数据报用来接收,这是一个输出型参数socket.receive(packet); //如果没有客户端进行访问,就会进行阻塞等待String request = new String(packet.getData(),0, packet.getLength()); //将这个数据报解析成字符串的形式String response = fun(request);DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,packet.getSocketAddress());//在构造的时候要将数据报转化为字符数组,并且指定IP地址和端口号发送,这里我们的IP地址和端口号,已经被存入到,packet.getSocketAddress()里面了System.out.printf("[%s :%d] req:%s,resp : %s\n",responsePacket.getAddress().toString(),responsePacket.getPort(),request,response);socket.send(responsePacket);}}private String fun(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoSever udpEchoSever = new UdpEchoSever(9090);udpEchoSever.start();}
}

3.2Client端

至于客户端,我们的逻辑就是,在构造方法里,要传入服务器的IP地址和端口号,以方便后续使用。

至于主方法,我们的大概思路分为以下几步
1.用户通过控制台输入,并且构造成DatagramPacket数据报,此时这个类里面应该有我们的数据和IP地址以及端口号

2.将这个数据报发送给服务器

3.从服务器拿到响应并且解析

4.将解析的响应打印出来

现在我们开始编程:

import javax.xml.ws.soap.Addressing;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {DatagramSocket socket = null;int severport;String severIp;public UdpEchoClient(String severIp,int severport) throws SocketException { //在构造方法中传入服务器的IP地址和端口号socket = new DatagramSocket();this.severIp = severIp;this.severport = severport;}public void start() throws IOException {Scanner scanner = new Scanner(System.in);System.out.println("客户端启动");while (true){System.out.print("->");if(!scanner.hasNext()){ //用户输入到回车等这些空字符以后就结束break;}String request = scanner.next();DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(severIp),severport); //将数据以及IP地址(这里的IP地址是字符串,// 所以我们需要调用InetAddress.getByName())以及端口号也写进去socket.send(requestPacket);//发送到服务器byte[] bytes = new byte[1024];DatagramPacket responsPacket = new DatagramPacket(bytes,bytes.length);//同样是输出型参数,所以要先有一个空的字符数组socket.receive(responsPacket);//接收服务器传来的响应String respons = new String(responsPacket.getData(),0,responsPacket.getLength());//将响应转化为字符串System.out.println(respons);//打印下来}}public static void main(String[] args) throws IOException {UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);udpEchoClient.start();}
}

我们来看看运行结果

 可以看到客户端没有问题。我们再来看看服务器端的控制台:

也和我们预期的结果一样

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

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

相关文章

Macos数据库管理软件:Navicat Premium for Mac 16.3.5中文版

Navicat Premium 16 for Mac是一款强大的数据库管理和开发工具,支持多种数据库系统,如MySQL、Oracle、SQL Server等。它提供了直观的用户界面和丰富的功能,使用户能够轻松地创建、管理和维护数据库。 软件下载:Navicat Premium fo…

基于CLIP4Clip的DRL的WTI模块实现

关于DRL的WTI模块: Weighted Token-wise Interaction: 直觉上,并非所有的单词和视频帧都同等重要。我们提供一种自适应方法,来调整每个标记的权重大小: 注:其中两个f函数都是MLP和softmax构成。 WTI的算…

Kotlin程序设计 扩展篇(一)

Kotlin程序设计(扩展一) **注意:**开启本视频学习前,需要先完成以下内容的学习: 请先完成《Kotlin程序设计》视频教程。请先完成《JavaSE》视频教程。 Kotlin在设计时考虑到了与Java的互操作性,现有的Ja…

【设计模式】张一鸣笔记:责任链接模式怎么用?

我将通过一个贴近现实的故事——请假审批流程,带你了解和掌握责任链模式。 什么是责任链模式? 责任链模式是一种行为设计模式,它让你可以避免将请求的发送者与接收者耦合在一起,让多个对象都有处理请求的机会将这个对象连成一条…

Ultraleap 3Di配置以及在 Unity 中使用 Ultraleap 3Di手部跟踪

0 开发需求 1、硬件:Ultraleap 手部追踪相机(Ultraleap 3Di) 2、软件:在计算机上安装Ultraleap Gemini (V5.2) 手部跟踪软件。 3、版本:Unity 2021 LTS 或更高版本 4、Unity XR插件管理:可从软件包管理器窗…

ICLR 2024 时间序列相关最新论文汇总,涉及transformer、GNN、大模型等热门领域

ICLR(International Conference on Learning Representations),国际公认的深度学习顶会之一,与AAAI、CVPR、ACL和NIPS等老牌学术会议齐名,由图灵奖巨头Yoshua Bengio和Yann LeCun牵头举办,在人工智能、统计…

【设计模式】适配器和桥接器模式有什么区别?

今天我探讨一下适配器模式和桥接模式,这两种模式往往容易被混淆,我们希望通过比较他们的区别和联系,能够让大家有更清晰的认识。 适配器模式:连接不兼容接口 当你有一个类的接口不兼容你的系统,而你又不希望修改这个…

finalshell连接linux的kali系统

kali的ssh服务似乎是默认关闭的,笔者在玩CentOS系统时可以直接用finalshell完成连接,但kali不行,需要先手动开启ssh服务。 开启kali的ssh服务 输入【ssh start】命令开启ssh服务,可以用【ssh status】命令查看ssh状态&#xff0c…

性能优化-OpenCL kernel 开发

「发表于知乎专栏《移动端算法优化》」 本文主要介绍OpenCL的 Kernel,包括代码的实例以及使用注意的详解。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC)开发基础教…

健康160 IPO之路出现“拦路虎”,如何“对症下药”?

自从2015年刮起了“互联网”的风,互联网医疗热被吹至风口浪尖,资本争先追逐。如今行业风口已过,互联网医疗企业上市的热度不降反增。一家健康之路,一家健康160,接连递表港交所。 健康160最早从挂号服务起家&#xff0c…

Android单元测试(五):网络接口测试

温馨提示:如果你不太熟悉单元测试,可以先看下之前四篇基础框架使用。便于你更好的理解下面的内容。 在平日的开发中,我们用后台写好给我们接口去获取数据。虽然我们有一些请求接口的工具,可以快速的拿到返回数据。但是在一些异常情…

LC 对角线遍历

LC 对角线遍历 题目描述: 给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。 题目实例: 示例一: 输入:mat [[1,2,3],[4,5,6],[7,8,9]] 输出:[…