Получение веб-страницы с сокетами - PullRequest
4 голосов
/ 09 декабря 2010

В настоящее время я занимаюсь изучением программирования сокетов и столкнулся с проблемой, с которой мне нужна помощь. Я пытаюсь написать небольшой класс Java, который будет подключаться к веб-хосту, загружать страницу по умолчанию, а затем отключаться от хоста. Я знаю, что для этого проще использовать URLConnection, но я пытаюсь изучить классы Sockets. Мне удалось подключиться к веб-серверу, но у меня возникли трудности с перетягиванием страницы. Это то, что у меня работает (и не работает) до сих пор:

import java.io.*;
import java.net.*;
import java.lang.IllegalArgumentException;
public class SocketsFun{
    public static void main(String[] myArgs){
        // Set some variables
        String theServer = null;
        String theLine = null;
        int thePort = 0;
        Socket theSocket = null;
        boolean exit = false;
        boolean socketCheck = false;
        BufferedReader theInput = null;

        // Grab the server and port number
        try{
            theServer = myArgs[0];
            thePort = Integer.parseInt(myArgs[1]);
            System.out.println("Opening a connection to " + theServer + " on port " + thePort);
        } catch(ArrayIndexOutOfBoundsException aioobe){
            System.out.println("usage: SocketsFun host port");
            exit = true;
        } catch(NumberFormatException nfe) {
            System.out.println("usage: SocketsFun host port");
            exit = true;
        }

        if(!exit){
            // Open the socket
            try{
                theSocket = new Socket(theServer, thePort);
            } catch(UnknownHostException uhe){
                System.out.println("* " + theServer + " does not exist");
            } catch(IOException ioe){
                System.out.println("* " + "Connection Refused");
            } catch(IllegalArgumentException iae){
                System.out.println("* " + thePort + " Not A Valid TCP/UDP Port.");
            }

            // Print out some stuff
            try{
                System.out.println("Connected Socket: " + theSocket.toString());
            } catch(Exception e){
                System.out.println("* " + "No Open Socket");
            }

            try{
                theInput = new BufferedReader(new InputStreamReader(theSocket.getInputStream()));
                while ((theLine = theInput.readLine()) != null){
                    System.out.println(theLine);
                }
                theInput.close();
            } catch(IOException ioe){
                System.out.println("* " + "No Data To Read");
            } catch(NullPointerException npe){
                System.out.println("* " + "No Data To Read");
            }

            // Close the socket
            try{
                socketCheck = theSocket.isConnected();
            } catch(NullPointerException npe){
                System.out.println("* " + "No Socket To Close");
            }
        }
    }
}

Все, что я хочу, это чтобы этот класс выдавал то, что может выводиться из "curl", "lynx -dump" или "wget" и т. Д. Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

6 голосов
/ 09 декабря 2010

У вас правильная идея, но вы не отправляете HTTP-запрос. Отправить:

GET / HTTP/1.1\r\nHost: <hostname\r\n\r\n

Это следует формату

[METHOD] [PATH] HTTP/1.1 [CRLF]
Host: [HOSTNAME] [CRLF]
OTHER: HEADERS [CRLF]
[CRLF]

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

РЕДАКТИРОВАТЬ Возможно, это поможет понять синтаксис HTTP-запроса, чтобы начать. Это довольно просто и просто хорошо знать вообще. Откройте терминал и используйте netcat (предпочтительно) или telnet. netcat google.com 80 или telnet google.com 80. Тип:

GET / HTTP/1.1[ENTER]
Host: google.com[ENTER]
[ENTER]

Я получаю ответ (после второго возврата):

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Thu, 09 Dec 2010 00:03:39 GMT
Expires: Sat, 08 Jan 2011 00:03:39 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block

<HTML&<HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

Как только вы почувствуете синтаксис запроса, просто запишите его в сокет, затем читайте строки, пока сервер не закроется, как вы делаете.

0 голосов
/ 09 декабря 2010

Вам нужно что-то записать в выходной поток сокета. Веб-серверы ждут запроса от клиента, прежде чем отправлять что-либо: запись «GET» попросит сервер вернуть страницу по умолчанию.

Ваш код ничего не пишет, поэтому сервер будет ждать вечно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...