java socket大数据传输丢失问题及解决

 更新时间:2024年08月10日 14:05:30   作者:yahahassr  
这篇文章主要介绍了java socket大数据传输丢失问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

java socket大数据传输丢失

最近遇见一个问题。利用java 的socket进行数据传输时,当数据量过大,比如4w个字节。

这时候我在客户端输出流将数据发送给服务器。

服务器如果利用数组接收时(即is.read(byte[])方法),接收到的数据不全。网上解决方法。

一、分批发送,分批读取,并不要直接读取

将输入输出流利用BufferedInputStream包装。

实测这种方法不能根本上解决问题,治标不治本。还是会有概率丢失。

二、实际上,数据是不会丢失的

即使输入数据过大导致溢出。数据也不会丢失。

根据观察,应该只是数据还没有传输过来,但是利用is.read(byte[])方法时,即使读取到的数据不到byte[]数组长度时,该方法也可以进行下去,不会阻塞!!!

譬如以下代码:

public class Test {
    @org.junit.Test
    public void server() throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true){
            Socket accept = serverSocket.accept();
            InputStream is = accept.getInputStream();
            byte[] bytes = new byte[5];
            int len = is.read(bytes);
            System.out.println(Arrays.toString(bytes));//发送端发送的数据只有两个字节,我们接收端设置为5个字节的字节数组,结果打印[1,2,0,0,0],而不会在上一步阻塞
        }
    }

    @org.junit.Test
    public void client() throws IOException {
        Socket socket = new Socket("127.0.0.1",8080);
        OutputStream os = socket.getOutputStream();
        os.write(new byte[]{1,2});
    }
}

从这个例子我们就知道为什么会丢失数据了。

原因有两点:

  • 网络延时
  • inputStream.read(byte[])方法读取的数据长度不一定等于byte[]数组长度

根据以上两点,修改后的接收端代码应该如此。

public static byte[] readData(InputStream is,int length) throws IOException {
        byte[] bytes = new byte[length];
        int index = 0;
        int len = 0;
        while(index < length){
            len = is.read(bytes,index,length - index);
            //每次读取完判断数据是否全部读取完毕
            if(len > 0){
                index += len;
            }else {
                break;
            }
        }
        return bytes;
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Bean创建和循环依赖

    Spring Bean创建和循环依赖

    这篇文章主要介绍了Spring Bean创建和循环依赖,讲述了Spring容器中 Bean 的创建过程已经主要的方法,另外也着重分析了循环依赖的问题,需要的小伙伴可以参考一下
    2022-05-05
  • Java线程休眠_动力节点Java学院整理

    Java线程休眠_动力节点Java学院整理

    sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。下面通过实例代码给大家介绍Java线程休眠的知识,需要的朋友参考下吧
    2017-05-05
  • java实现大数加法(BigDecimal)的实例代码

    java实现大数加法(BigDecimal)的实例代码

    之前写过用vector、string实现大数加法,现在用java的BigDecimal类,代码简单很多。但是在online-judge上,java的代码运行时间和内存大得多
    2013-10-10
  • 详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)

    详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)

    这篇文章主要介绍了java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • java IP归属地功能实现详解

    java IP归属地功能实现详解

    前一阵子抖音和微博开始陆续上了IP归属地的功能,引起了众多热议,有大批在国外的老铁们开始"原形毕露",被定位到国内来,那么IP归属到底是怎么实现的呢?那么网红们的归属地到底对不对呢
    2022-07-07
  • Java的反射机制之获取class详解

    Java的反射机制之获取class详解

    这篇文章主要介绍了Java的反射机制之获取class详解,Class类表示一个类或接口的元数据,通过它可以获取到类或接口的构造函数、方法、字段、注解等信息,也能够创建对象、调用方法等,需要的朋友可以参考下
    2023-09-09
  • ant打包jar文件脚本分享

    ant打包jar文件脚本分享

    本文介绍的ant脚本是用来打包jar文件,做完JAVA应用一定会用到这个,需要的朋友可以参考下
    2014-03-03
  • Java多线程中的wait、notify和park、unpark的使用详解

    Java多线程中的wait、notify和park、unpark的使用详解

    这篇文章主要介绍了Java多线程中的wait、notify和park、unpark的使用详解,它们都是线程之间进行协作的手段,都属于 Object 对象的方法,必须获得此对象的锁,才能调用这几个方法,需要的朋友可以参考下
    2023-12-12
  • SpringBoot集成slf4j2日志配置的实现示例

    SpringBoot集成slf4j2日志配置的实现示例

    本文主要介绍了SpringBoot集成slf4j2日志配置的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 详解java解决分布式环境中高并发环境下数据插入重复问题

    详解java解决分布式环境中高并发环境下数据插入重复问题

    这篇文章主要介绍了java解决并发数据重复问题 ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论