Потоковый сокет Java можно отправить только один раз - PullRequest
1 голос
/ 24 января 2011

Я пишу простой ускоритель загрузки.Проблема в том, что я могу отправлять и получать сообщения один раз.В следующий раз, когда я пытаюсь отправить и получить сообщение, я не получаю ответ от сервера.Я даже не уверен, что смогу отправить второе сообщение.

Первое сообщение что-то вроде;

*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

Ответы [ 2 ]

4 голосов
/ 24 января 2011

Первое сообщение что-то вроде;

HTTP/1.0\r\n  

Вы должны использовать HTTP версии 1.1, чтобы использовать несколько запросов для одного соединения TCP.

Из статьи Википедии по HTTP :

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


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

1 голос
/ 24 января 2011

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

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

...