2013-11-14 103 views
3

我试图通过套接字从服务器下载图像。我的代码工作正常,但是当我下载图像时,大小是正确的,但图像无法打开。我不知道我做错了什么。任何建议?谢谢通过套接字下载图像java

 Socket socket = new Socket(servername, 80); 
    DataOutputStream bw = new DataOutputStream(new DataOutputStream(socket.getOutputStream())); 
    bw.writeBytes("GET "+filename+" HTTP/1.1\n"); 
    bw.writeBytes("Host: "+servername+":80\n\n"); 

    DataInputStream in = new DataInputStream(socket.getInputStream()); 


    OutputStream dos = new FileOutputStream("testtttt.jpg"); 
    int count; 
    byte[] buffer = new byte[2048]; 
    while ((count = in.read(buffer)) != -1) 
    { 
     dos.write(buffer, 0, count); 
     dos.flush(); 
    } 
    dos.close(); 
    System.out.println("image transfer done"); 

    socket.close();  
    } 
+0

确定的形象是一个JPG,而不是一个PNG?你也可以尝试移除DataOutputStream的双重包装。 –

+0

谢谢你的回复。是的,我确定图片是以JPG格式,我删除了DataOutputStream的双重包装,但它仍然给我看图片和尺寸。它不会打开 – user2993368

+0

不要在循环内冲洗。如果你没有使用缓冲流,它什么也不做,如果你完全无法达到目的。没有理由不在这里使用'URL'和'HttpURLConnection',并完全避免所有的HTTP实现代码。 – EJP

回答

2

您需要在\ n之前的所有请求中添加\ r,另外您应该将输出流刷新到套接字。

Socket socket = new Socket(servername, 80); 
DataOutputStream bw = new DataOutputStream(socket.getOutputStream()); 
bw.writeBytes("GET "+filename+" HTTP/1.1\r\n"); 
bw.writeBytes("Host: "+servername+":80\r\n\r\n"); 
bw.flush(); 

此外,你会得到一些HTTP响应标题与您的请求。 Obiously这是你不想在你的图像信息,你的反应会是这个样子:

HTTP/1.1 200 OK 
Date: Thu, 14 Nov 2013 18:39:47 GMT 
Server: Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7 
Accept-Ranges: bytes 
ETag: W/"2956-1374616977919" 
Last-Modified: Tue, 23 Jul 2013 22:02:57 GMT 
Content-Type: image/png;charset=UTF-8 
Content-Length: 2956 

‰JPG....heres your image data 

我只是写了这个方法来摆脱跨越发送的HTTP报头。这个想法是不要在发生之前写入任何数据。该序列表示标题响应的结束,并且之前的任何数据都不是我们的图像。我知道有一个更清洁的方式做到这一点,但这种方式是快给我写的:)

OutputStream dos = new FileOutputStream("c:\\testtttt.jpg"); 
int count; 
byte[] buffer = new byte[2048]; 
boolean eohFound = false; 
while ((count = in.read(buffer)) != -1) 
{ 
    if(!eohFound){ 
     String string = new String(buffer, 0, count); 
     int indexOfEOH = string.indexOf("\r\n\r\n"); 
     if(indexOfEOH != -1) { 
      count = count-indexOfEOH-4; 
      buffer = string.substring(indexOfEOH+4).getBytes(); 
      eohFound = true; 
     } else { 
      count = 0; 
     } 
    } 
    dos.write(buffer, 0, count); 
    dos.flush(); 
} 
in.close(); 
dos.close(); 

您还可以找到另外一个问题像你这样在这里:Send HTTP Request manually via socket

+3

哇,我希望他把他的功课成绩传给你! – jtahlborn

+2

从套接字下载一个图像一个正常的作业问题?!...废话 –

+1

非常感谢代码,不期待这一点,尝试过,但仍然当我打开图像什么都没有出现。现在它给了我大小错误。我仍在搜索,但再次感谢 – user2993368

0

我的声望不够评论,所以不得不开始一个新的答案。
微克__的答案是伟大的,但行

buffer = string.substring(indexOfEOH+4).getBytes(); 

存在一些问题,缓冲区将被破坏。例如,

byte[] before = new byte[]{(byte)0xf1, (byte)0xf2, (byte)0xf3, (byte)0xf4}; 
String str = new String(before, 0, before.length); 
byte[] after = str.getBytes(); 

beforeafter不会是相同的。

所以我修改微克__的代码一点点:

OutputStream dos = new FileOutputStream("test.jpg"); 
int count, offset; 
byte[] buffer = new byte[2048]; 
boolean eohFound = false; 
while ((count = in.read(buffer)) != -1) 
{ 
    offset = 0; 
    if(!eohFound){ 
     String string = new String(buffer, 0, count); 
     int indexOfEOH = string.indexOf("\r\n\r\n"); 
     if(indexOfEOH != -1) { 
      count = count-indexOfEOH-4; 
      offset = indexOfEOH+4; 
      eohFound = true; 
     } else { 
      count = 0; 
     } 
    } 
    dos.write(buffer, offset, count); 
    dos.flush(); 
} 
in.close(); 
dos.close();