如何应用DataGram进行用户-服务器编程

简介:


《Java编程艺术》章节选登。作者:高永强 清华大学出版社 (即将出版)


23.2.5  Datagram编程 (1)

数据报表 Datagram ,或称数报式数据传输技术,利用 UDP 通讯协议( User Datagram Protocol ),进行用户 - 服务器间的数据传递,但 Java 虚拟机将 UDP  底层通讯细节隐藏,编程人员不必顾及其通讯协议和过程,只需利用 java.net 包中提供的 API 类 DatagramSocket 和 DatagramPacket 进行程序设计,调用适当的方法,实现用户 - 服务器编程。其中 DatagrameScoket 用来创建端口间的通讯,而 DatagramPacket 用来获取通过网络地址和端口以邮包方式( Packet )发送来的信息。表 23.4 列出了 java.net 包中 DataramSocket 和 DataramPacket 的常用构造器以及方法。
表 23.4  DatagramSocket 和 DatagramPacket 类的常用构造器以及方法
构造器 / 方法
解      释
DatagramSocket(int port,InetAdrress  address)
按指定端口和互联网地址创建对象。
  close()
关闭插座连接。
  connect(InetAddress address, int port)
按指定互联网地址和端口连接。
  disconnect()
断开当前的连接。
  InetAddress getInetAddress()
返回当前数报插座的互联网地址。
  InetAddress getLocalAddress()
返回当前数报插座的本机地址
  int getPort()
返回当前数报插座的连接端口。
  int getLocalPort()
返回当前数报插座的本机连接端口。
  receive(DatagramPacket packet)
接收当前数报插座的邮件。
  send(DatagramPacket packet)
发送当前数报插座的邮件。
DatagramPacket(byte[] buf, int length)
按指定缓冲数组合长度创建获取邮包的对象。
  InetAddress getAddress()
返回当前进行邮包传送的互联网地址。
  Byte[] getData()
返回当前发送或接收数据缓冲数组。
  int getLength()
返回当前发送或接收数据的长度。
  int getPort()
返回当前发送或接收数据的端口。
 
注意   DatagramSocket 和 DatagramPacket 抛出检查性异常,程序中必须提供处理这些异常的代码。具体实例见下面的讨论。
 
下面的例子利用 DatagramSocket 和 DatagramPacket ,模拟用户 - 服务器通讯,将用户        的英文输入,通过邮包发送到服务器端程序,转换为大写字母,并将结果传回到用户屏       幕。其功能类似于在 Socket 和 ServerSocket 讨论过的程序,但增加了统计并返回邮包长度的操作。图 23.7 显示了这个例子的一个典型运行结果。图上方为服务器端程序运行后的 截图。(注:截图未能显示。请参考原书)
图 23.7   利用 Datagram 的典型运行结果
如下是利用 Datagram 编写的服务器端程序的代码:
 
// 这个程序存在本书配套资源目录 Ch23 名为 DatagramServerTest.java
import java.io. * ;
import java.net. * ;
public class DatagramServerTest {
    public static void main(String[] args) {
        System.out.println(\"Welcome! The server is running....\");
        String line = \"Datagram packet from server: I love Java programming.\\n\";
        String promptString = line.toUpperCase() + \"Enter quit to STOP\";
        try {
             DatagramSocket socket = new DatagramSocket(1688);
                                                // 创建指定端口的 Datagram
             DatagramPacket receivePacket;      // 声明接收邮包
             byte[] buf = new byte[256];        // 缓冲器
             receivePacket = new DatagramPacket(buf, buf.length);
                                                // 创建接收邮包
             socket.receive(receivePacket);     // 接收邮包
             buf = promptString.getBytes();     // 内容至缓冲
             InetAddress address = receivePacket.getAddress();
                                                // 得到接收地址
             int port = receivePacket.getPort();// 得到接收端口
             sending(socket, buf, buf.length, address, port);
                                                // 调用发送邮包方法
             while (true) {
                 buf = new byte[256];        // 清除缓冲
                 receivePacket = new DatagramPacket(buf, buf.length);
                                                // 创建新邮包
                 socket.receive(receivePacket); // 接收
                 String receive = new String(receivePacket.getData());                                                  // 得到邮包内容
                 buf = receive.toUpperCase().getBytes();
                                                // 内容转成大写并送往缓冲
                 sending(socket, buf, buf.length, address, port);// 发送
                 buf = new byte[256];           // 清除缓冲
                 String wordCount = \"(Converting from server and packet length: \" + receive.trim().length() + \")\";
                 receivePacket = new DatagramPacket(buf, buf.length);                                                   // 创建新邮包
                 socket.receive(receivePacket); // 接收
                 buf = wordCount.getBytes();    // 发件内容送往缓冲
                 sending(socket, buf, buf.length, address, port);
                                                // 调用发送方法
             }
        }
        catch (IOException e) {
             e.printStackTrace();
        }
     }
    // 发送邮件方法
    public static void sending(DatagramSocket socket, byte[] buf, int length, InetAddress address, int port) {
            DatagramPacket sendPacket = new DatagramPacket(buf, length,                 address, port);
            try {
                socket.send(sendPacket);        // 发送
            }catch (IOException e) {
                e.printStackTrace();
            }
    }
 }
 
代码中首先接收用户端发送过来的一个空邮包,并利用这个邮包发送慰问和提示信息到用户。在循环中,接收用户发来的邮包内容,并将其转换成大写字母、统计字符串即邮包长度,调用自定义静态方法 sending() 将结果邮包发还给发来的用户。代码中在重新利用缓冲器发送新内容时,利用重新定义缓冲器来清除其原有内容。(待续



















本文转自高永强51CTO博客,原文链接: http://blog.51cto.com/yqgao/157391 ,如需转载请自行联系原作者
相关文章
|
Java
CompletableFuture在异常处理方面的一些常见问题和解决方案,建议牢记!
CompletableFuture在异常处理方面的一些常见问题和解决方案,建议牢记!
1244 0
CompletableFuture在异常处理方面的一些常见问题和解决方案,建议牢记!
|
存储 安全 Java
ArrayBlockingQueue 和 LinkedBlockingQueue 有什么区别?
ArrayBlockingQueue 和 LinkedBlockingQueue 有什么区别?
|
3月前
|
人工智能 网络协议 网络性能优化
【洛神公开课】第6期:AI网络白皮书-02训练网络篇
阿里云AI训练网络“三层引擎”(Scale-Up/Out/Across)突破万卡集群瓶颈:NVLink实现单机8卡全互联,HPN+eRDMA将跨机通信时延压至2μs,CEN+TR支撑跨域Tbps级协同。三者协同达成96%线性加速比,显著破解GPU空转难题。(239字)
611 1
|
3月前
|
数据采集 存储 人工智能
【洛神公开课】第5期:AI网络白皮书-01数据采集篇
AI训练常卡在“数据没到位”——PB级语料散落多源,搬运慢则每小时损失数十万元。本文详解阿里云AI数据采集网络:从高速专线、多云互联到OSS/CPFS分层存储,再到eRDMA直通GPU,构建稳定、高效、低成本的数据输送起跑线。(239字)
384 1
|
4月前
|
人工智能 Kubernetes 应用服务中间件
🚀【技术直播 · 重磅】Nginx Ingress 退役后,如何选对生产级网关?6月24日14:00-15:30,请锁定开发者社区直播间
"Nginx Ingress 不更新了,我该咋办?" 这场直播就是答案。 阿里云专家在线拆解迁移全流程,手把手教你不踩坑、不停服、不背锅。
415 2
|
4月前
|
运维 安全 容灾
【洛神公开课】第3期:阿里云全球化网络方案实操选型
本文系统解析阿里云全球化网络四大核心方案(专线、VPN、CEN、SD-WAN),覆盖企业出海、多云互联、跨境合规、低时延组网等典型场景,聚焦落地要点与避坑指南,助您高效构建安全、稳定、弹性的一张全球虚拟网。(239字)
592 0
|
4月前
|
弹性计算 负载均衡 网络协议
【洛神公开课】第2期:阿里云应用交付网络方案选型实操指南
本文是阿里云应用交付网络(ADN)的实战选型指南,聚焦ECS、IDC、K8s三类后端,厘清NLB/ALB/GA/Ingress定位与搭配逻辑,覆盖服务发现、低延连通、源IP透传、全球加速、安全容灾等关键场景,助你稳接每一次用户点击。(239字)
528 0
|
4月前
|
人工智能 运维 自然语言处理
阿里云Agent Infra香港首秀:170+机构到场,1700+人次互动
2025年5月21日,阿里云应邀出席由香港生产力促进局(HKPC)主办的"Innovating Public Services, Driving the AI Transformation" 大型人工智能主题盛会。本次活动汇聚香港政产学研各界力量,聚焦人工智能技术在政府治理、社会服务及产业转型中的创新应用。阿里云作为亚太地区领先的云计算与人工智能全栈服务商,深度参与本次活动,通过展台展示、技术分享及高层对话等多种形式,全面呈现阿里云在Agent Infra及智能体应用领域的最新成果,进一步夯实了阿里云在香港及粤港澳大湾区市场的影响力。
481 2
|
4月前
|
弹性计算 负载均衡 安全
【洛神公开课】第1期:如何设计一套安全、高可用、可扩展的 VPC 网络架构
从单 VPC 起步到多 VPC 互联的真实组网难题出发,拆解 VPC 划分原则、IP 规划十步法、TR 多场景互通、PrivateLink 共享服务、DMZ 统一公网出入口五大主题,并附产品选型对照表,帮你少踩弯路、把架构一次画对。
446 0
|
6月前
|
人工智能 运维 安全
别让“龙虾”裸奔!企业规模化“养虾”亟需新一代云网架构护航
本文深入分析了千级 AI Agent 规模化部署时面临的网络架构挑战,包括单 VPC 带宽天花板、安全组规则爆炸、混合云互通复杂等三大硬伤。基于阿里云 ACS+VPC+TR+CEN 的分层隔离架构,提供按业务域划分 VPC、TR 统一路由枢纽、CEN 全球互联的完整解决方案,实现性能隔离、故障隔离、安全合规、弹性扩展和成本优化五大核心价值。适用于 Agent 数量>500、多地域部署、强合规行业及混合云架构的企业场景。
792 6
别让“龙虾”裸奔!企业规模化“养虾”亟需新一代云网架构护航