iteye_12142 2010-07-01 11:14
浏览 462
已采纳

网络传输文件丢字节的问题

碰到一个奇怪的问题, 用客户端程序向服务端servlet传输图片文件的时候,总是丢失字节数, 收到的字节数组变小了。发送之前统计的是 229237字节 服务端收到的却是 229056字节

在服务端保存之后,保存之后的图片文件无法打开。 不知各位是否碰到这种问题。

客户端代码

[code="java"]String url ="http://127.0.0.1/api?photo_type=jpg";

    try {
     URL dataUrl = new URL(url);
     HttpURLConnection con = (HttpURLConnection) dataUrl.openConnection();
     con.setRequestMethod("POST");
     con.setRequestProperty("Proxy-Connection", "Keep-Alive");
     con.setDoOutput(true);
     con.setDoInput(true);
     OutputStream os=con.getOutputStream();
     FileInputStream in = new java.io.FileInputStream("c:\\test.jpg");  
     byte[] bt = new byte[1024];  
     while ((count = in.read(bt)) > 0) {  
         os.write(bt, 0, count);  
         os.flush();

     }  
     in.close();  
     os.flush();
     os.close(); 
     InputStream is=con.getInputStream();
     DataInputStream dis=new DataInputStream(is);
     byte d[]=new byte[dis.available()];
     dis.read(d);

     con.disconnect();
    } catch (Exception ex) {
     ex.printStackTrace();
    }[/code]

服务端代码:
[code="java"]try {

        long randomPre = System.currentTimeMillis();
        Random rand = new Random();
        fileTemp = fileTemp + String.valueOf(randomPre) + "_" + rand.nextInt() + "." + photo_type;
        outputStream = new FileOutputStream(new File(fileTemp));
        byte[] bytes = new byte[1024];
        int v;
        while ((v = request.getInputStream().read(bytes)) > 0) {
            outputStream.write(bytes, 0, v);

        }
        outputStream.flush();
        outputStream.close();


    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }[/code]
  • 写回答

5条回答

  • xanpeng 2010-07-06 14:05
    关注

    [quote]恩 有点明白了,貌似传的时候有一定的格式,有一些token和一些 boundary分隔符之类的数据,是这样的吗? 请继续指教 我该怎么在http里接受post过来的图片另存呢[/quote]
    不好意思,最近比较忙,没有及时答复

    我做了一个简单的实验, 下面列出代码, 这些代码在我机器上运行能得到正确的效果:
    1) 使用 WireShark 可以接获 POST 数据, 如下图
    [img]http://dl.iteye.com/upload/picture/pic/66426/057aae68-eba3-3ba3-99f0-72eaece03198.jpg[/img]

    这里截获的是人人网上传照片的POST数据, 从图片可以看出 POST Image 数据的一些基本格式

    2) 但是这个格式是抽象好的, 我就通过代码打印出 POST 的数据, 然后针对性地分析这些数据, 得到正确的图片, 主要代码如下:
    [code="java"]
    private void doFileUpload(HttpServletRequest request,
    HttpServletResponse response)
    throws IOException {
    String tempFile = String.format("%s%d.jpg", fileRoot, new Random().nextInt());
    logger.debug("file name:" + tempFile);
    logger.debug("before transferring bytes in Servlet");
    File file = new File(tempFile);
    logger.debug("file path: " + file.getAbsolutePath());
    logger.debug("file size: " + file.length());

        OutputStream outputStream = new FileOutputStream(file);
        byte[] bytes = new byte[1024];
        int count = -1;
        ServletInputStream in = request.getInputStream();
        String line = null;
        boolean flag = false;
        while ((count = in.read(bytes)) > 0) {
            int start = 0;
    
            line = new String(bytes, 0, count);
            logger.debug("get bytes: " + count);
            logger.debug(line);
            if (line.startsWith("-----------------------------")) {
                int ndxContentDisp = line.indexOf("Content-Disposition");
                int ndxContentType = line.indexOf("Content-Type", ndxContentDisp);
                if (-1 != ndxContentDisp && -1 != ndxContentType) {
                    flag = true;
                } else {
                    flag = false;
                }
                start = line.indexOf("\r\n", ndxContentType);
                start = start + 4;
                logger.debug("****** flag of start *******: " + flag + ", start index: " + start);
            } else if (line.startsWith("Content-Disposition")) {
                flag = true;
                continue;
            } else if (line.startsWith("Content-Type")) {
                flag = true;
                continue;
            }
            if (flag) {
                outputStream.write(bytes, start, count - start);
            }
        }
        outputStream.flush();
        outputStream.close();
        logger.debug("after transferring bytes in Servlet");
    }
    

    [/code]

    客户端页面代码很简单, 如下
    [code="XML"]

    [/code]

    在 2) 的代码中, 我很有针对性地处理了 POST 的数据, 其中图片的数据是包含在一定的边界之中的, 并非InputStream的所有数据. 分清楚这个边界, 取得正确的图片数据, 就能得到正确的结果.

    具体的 POST multipart 数据的格式, 还要参考 HTTP Protocol 的对应部分: http://www.ietf.org/rfc/rfc2388.txt

    使用 Apache FileUpload 组件, 可以省去处理这些处理细节

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题