3

ソケットを介してサーバーからイメージをダウンロードしようとしています。私のコードは正常に動作しますが、画像をダウンロードすると、サイズは正しいのに画像が開きません。何が間違っているのかわかりません。なにか提案を?ありがとうございました

     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();     
   }
4

2 に答える 2

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 レスポンス ヘッダーを取得します。明らかに、これは画像に含めたくない情報です。応答は次のようになります。

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 ヘッダーを取り除くために、このメソッドを作成しました。\r\n\r\n が発生する前にデータを書き込まないようにするという考え方です。そのシーケンスはヘッダー応答の終わりを表し、それより前のデータはイメージではありません。それを行うためのよりクリーンな方法があることは知っていますが、この方法は私が書くのが速かったです:)

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();

ここであなたのような別の質問を見つけることもできます: HTTP リクエストをソケット経由で手動で送信する

于 2013-11-14T18:51:05.290 に答える
1

私の評判はコメントするのに十分ではないので、新しい答えを始めなければなりません.
ug__の答えは素晴らしいですが、その行は

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();

before同じではありafterません。

そこで、ug__ のコードを少し修正しました。

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();
于 2015-04-25T06:21:28.690 に答える