2011-01-24 6 views
1

私は簡単なダウンロードアクセラレータを書いています。問題は、一度メッセージを送受信できることです。次回にメッセージを送受信しようとすると、サーバーからの応答はありません。私は第二のメッセージを送ることができるかどうかもわかりません。Javaストリームソケットは一度だけ送信できます

最初のメッセージは次のようなものです。

*HEAD /TIPS/LAWLER/PANOHOW2.PDF HTTP/1.0\r\n 
HTTP/1.0\r\n 
Connection: close\r\n 
\r\n* 

です。

*HTTP/1.1 200 OK 
Date: Mon, 24 Jan 2011 10:53:38 GMT 
Server: Apache 
Last-Modified: Tue, 
22 Sep 1998 13:19:52 GMT 
ETag: "1968013-2b4f4-3386e15b6ee00" 
Accept-Ranges: bytes 
Content-Length: 177396 
Connection: close 
Content-Type: application/pdf* 

私はメッセージに感謝します。

GET /TIPS/LAWLER/hedeh/PANOHOW2.PDF HTTP/1.0\r\n 
Range: bytes=0-44349\r\n 
Connection: close\r\n 
\r\n 

何も得られません。

私のコードで何が問題になっていますか?

public class Main { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 



      //Parse URL 
      String cmd = "http://www.imaging-resource.com"; //Host Name 
      if (cmd.contains("http://")) 
      { 
       cmd = cmd.substring(7); // 
       if (cmd.contains("/")) 
       { 
        int index = cmd.indexOf("/"); 
        cmd = cmd.substring(0, index); 
        System.out.println(cmd); 
       } 
      } 
      String str = "HEAD /TIPS/LAWLER/PANOHOW2.PDF HTTP/1.0\r\nConnection: close\r\n\r\n"; //First message to send 




      //Create socket, connect, initialize read and write handlers 
      //in, out 
      Socket socket = null;   //Create a client socket 
      SocketAddress sockaddr = null; 
      InetAddress address = null; 
      InputStream input = null;  //Input handler 
      OutputStream output = null; //Output handler 

      try 
      { 
       address = InetAddress.getByName(cmd);   //Get ip using host name 
       socket = new Socket();       //Contrusct Socket 
       sockaddr = new InetSocketAddress(address, 80); 
       //socket.setTcpNoDelay(false); 
       socket.connect(sockaddr, 2000);     //Connect to server set and timeout to 2 sec 
      } //End of try Block 
      catch (Exception ex) 
      { 
       Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
       System.out.println(ex); 
      } //End of catch Block 

      if (!socket.isConnected()) 
      { 
       System.out.println("not connected"); 
       System.exit(-1); 
      } 


      //Sending package here 
      try 
      { 
       int c; 
       byte[] buf = new byte[65535]; 
       char[] chr = new char[65535]; 


       input = socket.getInputStream();   //Input handler is created 
       output = socket.getOutputStream();   //Output handler is created 
       buf = str.getBytes();      //HEAD message converted into byte array 
       output.write(buf);       //Sending message to server 
       output.flush(); 
       int counter = 0; 


       while ((c = input.read()) != -1)  //Reading received package 
        chr[counter++]=(char)c; 


       //input.reset(); 
       str = new String(chr);     //For better manipulation, server message is converted to string 
       System.out.println(str); 

      } catch (IOException e) 
      { 
       System.err.print(e); 
      } //End of catch 








      int index = str.indexOf("Content-Length"); //Look for "Content-Length" in response 
      str = str.substring(index);     //Using its beginning index create an substring   
      index = str.indexOf("\r\n");    //Search for end of line 
      str = str.substring(0, index);    //Erase end if line chars - \r\n 
      str = str.substring(16, str.length());  //"Content-Length: " 16 chars 
      int fileSize = Integer.parseInt(str);  //Lentgh of file is converted to Integer 


      int[][] parts = new int[4][2];    //Beginning and en of jobs for threads will be stored here 
      int remainder = fileSize;     //Bytes left to split for rest of the threads will be stored here 
      int start = 0; 
      int finish = 0; 

      for (int i = 0; i < 4; i++)     //Number of threads many times 
      { 
       parts[i][0] = start;      //*******Each threads job Interval(eg. 0-108) 
       //System.out.print(parts[i][0] + "-");  //****** 
       finish += remainder/4 - i;    //***** 
       parts[i][1] = finish;      //**** 
       start = finish + 1;       //*** 

       if (i + 1 == 4) 
       parts[i][1] = fileSize;      //* 
      } 

      str = "GET /TIPS/LAWLER/hedeh/PANOHOW2.PDF HTTP/1.0\r\nRange: bytes=" + parts[0][0] + "-" + parts[0][1] + "\r\nConnection: close\r\n\r\n"; 
      //System.out.println(str); 


      if(!socket.isConnected()) 
      { 
       System.out.println("closed"); 
       try 
       { 
        socket.connect(sockaddr, 2000); 
       }//End od try 
       catch(Exception e){ 
       System.err.print(e); 
       }//End of catch 
      }//End of If 
      System.out.println("Is Outputhandler closed :"+socket.isOutputShutdown()); 
      System.out.println("Is Inputhandler closed :"+socket.isInputShutdown()); 



      try 
      { 

       int c; 
       byte[] buf = new byte[65535]; 
       char[] chr = new char[65535]; 


       buf = str.getBytes();      //Output handler is created 
       output.write(buf);       //Sending message to server 
       output.flush(); 
       int counter = 0; 

       if((c = input.read()) != -1) 
       { 
        chr[counter++] = (char) c; 

        while ((c = input.read()) != -1)    //Reading received package 
        { 
         System.out.println("response is not -1"); 
         chr[counter++]=(char)c; 
        } 


        str = new String(chr);     //For better manipulation, serve message is converted to string 
        System.out.println("Response "+str); 
       }//End of If 

       else System.out.println("No Response!"); 


      }catch(Exception e) 
      {System.err.print(e);} 

      //Closing open stuff 
      try { 
       output.close(); 
       input.close(); 
       socket.close(); 
      } catch (Exception e) { 
       System.out.println(e); 
      } 




    }// End of main method 
}//End of class definition 

答えて

4

最初のメッセージは次のとおりです。

HTTP/1.0\r\n 

単一のTCP接続で複数の要求を使用するには、HTTPバージョン1.1を使用する必要があります。 Wikipedia article on HTTPから

:HTTPで

/0.9および1.0は、接続は、単一の要求/応答のペアの後に閉じられます。 HTTP/1.1では、複数の要求に対して接続を再利用できるキープアライブメカニズムが導入されました。


@Joachimザウアーはコメントで指摘するようにまた、あなたが明示的にあなたのヘッダー内のConnection: closeを言っています。 :-)

+1

彼は明示的な 'Connection:close'も送信しています。したがって、HTTP/1.1を使用していてもまだ動作しません。 –

+0

ああ、良い点...それほど遠くを読まなかった;-)回答が更新されました。 – aioobe

1

普通のTCPソケットを使用してHTTPサーバーに接続しようとしていることが問題だと思います。はい、HTTPはTCPの上にありますが、多くのことを知るためには複雑なプロトコルです。私は、HTTPプロトコルを実装しているより高レベルのAPIで作業することをお勧めし、より便利なAPIを提供します。

最も簡単な例は、JDKのURL + URLConnectionです。おそらくジャカルタのHttpClientが良いでしょう。

+1

Semi + 1:HTTP *の一部(限られたサブセット)は簡単に "手作業で"実装できますが、それを実行する正当な理由はほとんどありません。既存のよくテストされたHTTPクライアントがそこにたくさんあります。手動で実装する必要はありません。 –

+0

この宿題では、ソケットを明示的に使用する必要があります。私はHttpClientを使用することが許されたと思う。 – mcaner

関連する問題