开发者

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

开发者 https://www.devze.com 2024-08-11 10:45 出处:网络 作者: yahahassr
目录Java socket大数据传输丢失一、分批发送,http://www.devze.com分批读取,并不要直接读取二、实际上,数据是不会丢失的总结java socket大数据传输丢失
目录
  • Java socket大数据传输丢失
    • 一、分批发送,http://www.devze.com分批读取,并不要直接读取
    • 二、实际上,数据是不会丢失的
  • 总结

    java socket大数据传输丢失

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

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

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

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

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

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

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

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

    根据观察,应该只是数据还没有传输过来,但是利用is.read(byte[])方法时,即使读取到的数据php不到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 {
       android     Socket socket = new Socket("127.0.0.1",8080);
            OutputStream os = socket.getOutputStream();
            os.write(new byte[]{1,2});
        }
    }

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

    原因有两点:

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

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

    public static byte[] readData(InputStjavascriptream 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;
        }

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消