2011-01-24 4 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* 

Когда я прихожу к сообщению sen;

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 

Вы должны использовать HTTP версию 1.1 для использования нескольких запросов в одном TCP-соединении.

От Wikipedia article on HTTP:

В HTTP/0.9 и 1.0, соединение закрывается после одной пары запрос/ответ. В HTTP/1.1 был введен механизм keep-alive, где соединение можно было повторно использовать для нескольких запросов.


Кроме того, как @Joachim Sauer указывает в комментариях, вы явно говорят Connection: close в вашем заголовке. :-)

+1

Он также отправляет явное «соединение: закрыть», поэтому даже при использовании HTTP/1.1 он все равно не будет работать. –

+0

А, хороший момент ... Не читал, что далеко ;-) Ответ обновлен. – aioobe

1

Я думаю, что проблема в том, что вы пытаетесь подключиться к HTTP-серверу, используя простой TCP-сокет. Да, HTTP находится поверх TCP, но это сложный протокол, который требует многого, что нужно знать. Я предлагаю вам работать с API более высокого уровня, который реализует протокол HTTP и предоставляет вам более удобный API.

Простейшим примером является URL + URLConnection от JDK. Вероятно, лучше HttpClient из Джакарты.

+1

Semi- + 1: Хотя (ограниченное подмножество) HTTP * может * легко быть реализовано «вручную», едва ли есть веская причина: есть тонны существующих, хорошо протестированных HTTP-клиентов, поэтому его не нужно выполнять вручную. –

+0

В этой домашней работе я должен явно использовать сокеты. Мне жаль, что мне не разрешили использовать HttpClient. – mcaner

 Смежные вопросы

  • Нет связанных вопросов^_^