Java DatagramPacket 中的坑
转载请注明来源
目录
问题说明
这里给出两种解决方法
方法一:使用getLength()截取更新的数据部分。下图中,使用substring(0,p.getLength())截取了p.getData()中被更新的数据部分。
方法二:每次接收数据开始前,对DatagramPacket的数据进行置零。下图中,从第一次开始,都对DatagramPacket前getLength()个字节的数据进行置零。
总结
附测试代码
问题说明
DatagramPacket的两个方法getData()和getLength()是不对应的。getLength()反映了刚刚接收到的数据的长度,而getData()反映了DatagramPacket对应缓冲区中的新接收到的数据和未被覆盖的旧数据,当我们使用DatagramPacket来处理新接收到的数据时,就容易同时触及到旧数据导致混乱。下图所示,udp客户端Client A第一次收到了数据“welcome",getData()获得的数据是”welcome",getLength()的结果是7;ClientA第二次收到了数据“hi",getData()获得的数据是”hilcome",其保留了旧数据“welcome"未被覆盖的部分”lcome",而getLength()的结果是2,即“hi"的长度。
这里给出两种解决方法
方法一:使用getLength()截取更新的数据部分。下图中,使用substring(0,p.getLength())截取了p.getData()中被更新的数据部分。
方法二:每次接收数据开始前,对DatagramPacket的数据进行置零。下图中,从第一次开始,都对DatagramPacket前getLength()个字节的数据进行置零。
总结
方法一和方法二都能得到正确结果,但是方法二对缓冲区buf进行了直接操作,很容易发生数组元素访问越界的错误。在DatagramPacket 被receive时,缓冲区buf的length不变,DatagramPacket允许接收的最大字节数也不变;而getLength()的结果发生变化;新数据只是在缓冲区中从偏移量开始覆盖旧数据,如果旧数据长度更大,则保留部分旧数据。
建议使用方法一
附测试代码
package udp_test1.udp_client;//library
import java.io.*;
import java.net.*;
import java.util.Scanner;class Recv_Thread extends Thread{private byte [] buf;private DatagramSocket ds = null;private DatagramPacket p = null;public Recv_Thread(int buf_len, DatagramSocket ds) {buf = new byte[buf_len];this.ds = ds;p = new DatagramPacket(buf,250);}@Overridepublic void run() {while(true) {try {ds.receive(p);String str = new String(p.getData()).substring(0,p.getLength());System.out.println("来自["+p.getPort()+"]的数据:"+str);}catch(Exception e ) {e.printStackTrace();}} }
}
class Send_Thread extends Thread{private DatagramSocket ds = null;private InetAddress des_address = null;private int des_port;Scanner s = new Scanner(System.in);Send_Thread(DatagramSocket ds, InetAddress des_address,int des_port){this.ds = ds;this.des_address = des_address;this.des_port = des_port;}@Overridepublic void run() {while(true) { try {byte[] buf = s.nextLine().getBytes();DatagramPacket p = new DatagramPacket(buf,buf.length,des_address,des_port);ds.send(p);}catch(Exception e) {e.printStackTrace();}}}
}public class Udp_Client extends Thread{private DatagramSocket ds = null;private InetAddress des_address = null;private int des_port = 0;private int buf_len = 256;private Send_Thread st = null;private Recv_Thread rt = null;public Udp_Client(int src_port,int des_port, InetAddress des_address) {this.des_port = des_port;this.des_address = des_address;try{ds = new DatagramSocket(src_port);System.out.println("本地开启UDP "+src_port+" 端口");}catch(IOException e ) {e.printStackTrace();}}@Overridepublic void run() {try {st = new Send_Thread(ds,des_address,des_port);st.start();rt = new Recv_Thread(buf_len,ds);rt.start(); st.join();rt.join();}catch(Exception e) {e.printStackTrace();}ds.close();}
}
Java DatagramPacket 中的坑相关推荐
- java正则表达式中的坑String.matches(regex)、Pattern.matches(regex, str)和Matcher.matches()
问题:程序会计算表达式的值 //将数值转换以K为单位 String value = "10*1000*1000"; String regex="\\s*\\*\\s*10 ...
- JAVA异常中的坑--trytry-catch-finally的执行顺序
结论: 不管有没有出现异常,finally代码块都会执行: 不管try和catch的代码块中有return时,finally仍会执行,且如果finally代码块也有return,则此代码肯定会返回fi ...
- java专业编码_java编码中的坑(记一次解决编码BUG的经历) - 贪吃蛇学院-专业IT技术平台...
1.2016年11月15日(周二),我被经理外派出差渝北金开大道,任务:解决那边的一个数据库乱码异常 2.那边的负责人描述:数据库原是utf8编码,他为了兼容emoji表情,改为utf8mb4,之后出 ...
- JDK中的坑:JDK中这些方法的bug你不要踩
点击关注公众号,Java干货及时送达 图片来源:白夜追凶 前言: jdk作为我们每天必备的调用类库,里面大量提供了基础类供我们使用.可以说离开jdk,我们的java代码寸步难行,jdk带给我们的便利可 ...
- Java 8 中 Map 骚操作之 merge() 的用法
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | juejin.im/post/5d9b455a ...
- Java 语言中十大“坑爹”功能!
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源:https://www.sohu.com/a/35 ...
- Java web 开发填坑记 2 -如何正确的创建一个Java Web 项目
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72566261 本文出自[赵彦军的博客] Java web 开发填坑记 1-如何正确 ...
- 第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密 java.lang.ClassNotFoundException 踩坑解决问题详细内幕版本
第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密 /* * *王家林老师授课http://weibo.com/ilovepains */ 每天晚上20: ...
- 缓存详解-在java项目中使用缓存
目录 一.概述 二.java常用的缓存 三.使用缓存将会面临的一些问题 穿透 雪崩 击穿 总结 三.缓存淘汰策略 缓存淘汰 在Spring项目中优雅的实现缓存 二级缓存推荐的实现 一.概述 在java ...
最新文章
- 场景法:基本流、备选流、构造场景
- 【Windows系统】基于vscode搭建go语言开发环境
- 50 xen虚拟化技术基础、xen虚拟化技术进阶
- Java中使用Observer接口和Observable类实践Observer观察者模式
- 不足补0 java_Java Android 开发数字不足位数前面补0
- github操作实用命令
- 小白spss学习笔记(一)
- ios下input框 数字键盘问题
- 如何恢复扩展属性为u的linux文件,chattr - 修改文件在Linux第二扩展文件系统(E2fs)上的特有属性...
- python sasl_python用sasl的方式连接ldap提示
- 关于录制短视频点播不能播放问题的总结
- JAVA入门-024(int的正负数)
- 三大运营商eSIM商用情况
- 计算机共享不了,电脑的共享开不了怎么办
- python一只青蛙一次可以_python算法题 python123网站单元四题目
- 高速PCB(五) 信号层覆铜选择困难症
- 华为OD德科面试+机试记录
- html图片浮动特效
- putty乱码问题及解决
- Unity性能优化之字体篇
热门文章
- 【已解决】ffmpy3.FFExecutableNotFoundError: Executable ‘ffmpeg‘ not found
- 【Linux】Linux进阶指令
- 火星人谚语系列之四:对问题最深入的认识是知道答案
- 算法应用-斐波那契数列
- Android 蓝牙开发(2)——低功耗蓝牙
- 525 Contiguous Array 连续数组
- Centos7的iso everything与DVD以及Live的区别
- StringUtils一些常用方法
- impala 使用记录
- Xcode引入了第三方的类库之后真机调试提示莫名其妙的错误