wzltina 2010-11-25 11:07
浏览 864
已采纳

关于java 不能完全读取socket二进制流的问题(数据量越大问题就越严重)

我在java中用socket读取server端发过来的二进制流,从包头前面11个字节中读取包体的字节总数,然后再循环读取包体的字节数,但当server端的数据字节比较大时就不能完全读过来 ,如从server端发送了 3万个字节,这时client端程序就会不能完全读出server端的字节,可能只能读2万多个; 当字节数少于2000 以下时,就基本没有出现过问题。
我把程序贴出来,这段程序有什么问题么?接收大量的数据该如何处理为好?
想了很久,没想明白是怎么回事,望各位不吝赐教!!!

public class SocketService {

private static Socket socket;
private static InputStream is;
private static OutputStream os;
private static BufferedInputStream br;

public static byte[] getReceiveBytes(Catalog catalog,byte[] b) {
    byte[] receive_body_byte = {};
    try {
    socket = new Socket(catalog.getPrivateTcpIp(), Integer.parseInt(catalog.getPrivateTcpIPPort()));

        is = new DataInputStream(socket.getInputStream());
        os = new DataOutputStream(socket.getOutputStream());
        os.write(b);
        br = new BufferedInputStream(is);

        // 包体长度 packlength。
        String packlength = "";

                        // 先收11个字节,函数解析出数据包长度 
        byte[] encry_byte = new byte[11];       
        int sizeHead = br.read(encry_byte);
        for (int m = 0; m < sizeHead; m++) {
            if (m > 6) {
                packlength = packlength + Util.byte2HexStr(encry_byte[m]);
            }
        }
        receive_body_byte = new byte[Integer.parseInt(packlength, 16)];
                         // 接收剩下的字节
        int size = br.read(receive_body_byte);
        //打印接收到的字节
        System.out.println("\n-------接收到的字节总数是-------------- "+receive_body_byte.length);

        os.flush();
        is.close();
        os.close();
        br.close();
    } catch (Exception e) { 
                    System.out.print("**********Socket异常!!!!*********"+e.getMessage());
                    return null;
    }

    return receive_body_byte;
}

========= 上面的程序不知哪里有问题,于是我就又优化了一下,代码如下,但遇到大数据还是不能全读出来===================

       public class SocketService {

private static Socket socket;
private static InputStream is;
private static OutputStream os;
private static BufferedInputStream br;

public static byte[] getReceiveBytes(Catalog catalog,byte[] b) {
    byte[] receive_body_byte = {};
    try {
    socket = new Socket(catalog.getPrivateTcpIp(), Integer.parseInt(catalog.getPrivateTcpIPPort()));

        is = new DataInputStream(socket.getInputStream());
        os = new DataOutputStream(socket.getOutputStream());
        os.write(b);
        br = new BufferedInputStream(is);

        // 包体长度 packlength。
        String packlength = "";

                        // 先收11个字节,函数解析出数据包长度 
        byte[] encry_byte = new byte[11];       
        int sizeHead = br.read(encry_byte);
        for (int m = 0; m < sizeHead; m++) {
            if (m > 6) {
                packlength = packlength + Util.byte2HexStr(encry_byte[m]);
            }
        }
        receive_body_byte = new byte[Integer.parseInt(packlength, 16)];
                            int size = 0
        //  分次取server端的数据,即每次从流中取1024个字节,不足1024就一次取过来
        while(true){
        int a = receive_body_byte.length/1024;

        if(a>=1){
            int last=0;
            Thread.sleep(280);
            for(int i=0;i<a;i++){
                //Thread.sleep(50);
                byte[] btmp = new byte[1024];
                br.read(btmp);
                    getBytes(receive_body_byte,i*1024,btmp);
                    last = last + i*1024;
                    Thread.sleep(100);
                }
                //然后取剩余不足1024个的字节
                int aa = receive_body_byte.length%1024;
                byte[] bmp = new byte[aa];
                //Thread.sleep(200);
                if(aa!=0){
                    br.read(bmp);
                    System.out.println(" aa------------"+aa);
                    p(bmp);
                    Thread.sleep(100);
                    getBytes(receive_body_byte,a*1024,bmp);
                }
                break;
            }else{

                br.read(receive_body_byte);
                break;
            }
        }
        //打印接收到的字节
        System.out.println("\n-------接收到的字节总数是-------------- "+receive_body_byte.length);

        os.flush();
        is.close();
        os.close();
        br.close();
    } catch (Exception e) { 
                    System.out.print("**********Socket异常!!!!*********"+e.getMessage());
                    return null;
    }

    return receive_body_byte;
}
  • 写回答

14条回答

  • enet_java 2010-11-25 16:40
    关注

    类似的问题,我也遇到过,我使用如下代码以后,就没有这个问题了,供你参考,

    // 读取实际的对象内容
    buffer = new byte[objContentleng];
    int nIdx = 0;
    int nTotalLen = buffer.length;
    int nReadLen = 0;

                while (nIdx < nTotalLen)
                {
                    nReadLen = bis.read(buffer, nIdx, nTotalLen - nIdx);
    
                    if (nReadLen > 0)
                    {
                        nIdx = nIdx + nReadLen;
                    }
                    else
                    {
                        break;
                    }
                }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(13条)

报告相同问题?

悬赏问题

  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素