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

碰到一个奇怪的问题, 用客户端程序向服务端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]

[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 组件, 可以省去处理这些处理细节

你直接往一个http上写binary,肯定有问题啦!

Post Image 是有一定格式的, 不能直接从头读取 Stream

你可以自己把图片用base64编码再传么,然后在服务器端解码就成啦。 :lol:

没有碰到过这种情况,好好检查下你的代码。应该是代码有问题。