2012-03-31 2 views
1

Я пытаюсь написать простой HTTP-клиент Java, который просто распечатывает одну строку ответа сервера. Моя проблема в том, что я не получаю ответа от сервера. Вот что я имею, который компилируется и работает без явных ошибок, он просто зависает после ввода имени хоста, например. 'www.google.com':Простой java-клиент http-сервера нет ответа сервера

import java.io.*; 
import java.net.*; 

public class DNSTest { 
    // Constructor 
    public DNSTest() { } 

    // Builds GET request, opens socket, waits for response, closes 
    public static void main(String[] args) throws Exception{ 
     String line; 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     //For each hostname 
     while ((line = br.readLine()) != null){ 
      //Resolve the hostname to an IP address 
      InetAddress ip = InetAddress.getByName(line); 

      //Open socket on ip address 
      Socket socket = new Socket(ip, 80); 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

      //Send request 
      out.println("GET /index.html HTTP/1.0\n"); 

      //Read one line of input 
      System.out.println("Response from "+line+": "+in.readLine()); 

     } 
    } 
} 

Любые предложения? Обратите внимание, что это предполагает, что существует «index.html» - он все еще просто зависает, даже если это правда.

+1

Используйте отладчик, чтобы увидеть, где вы код висит. – Hiro2k

+0

Я знаю out.println ("GET /index.html HTTP/1.0 \ n"); выходит, но System.out.println («Ответ от« + строка + »:« + in.readLine()); никогда не вызывается. –

+1

Работает для меня. Я получаю: «Ответ от www.google.com: HTTP/1.0 302 Найдено». –

ответ

3

I t hink Я смог воспроизвести проблему, применив небольшое изменение к коду, так что теперь он не работает на моей машине и проявляет то же поведение, что и в вашей среде. Я только что сменил звонок out.println на более простой out.print, и вот, программа зависает после, отправив запрос, но до последний println звонок.

Насколько я помню, HTTP-запросы должны содержать пустую строку после заголовков, где разделителем строк должна быть пара символов символов \r\n. Я полагаю, что ваша среда такова, что println не отправляет правильные разделители строк (вы можете проверить значение System.getProperty("line.separator"), чтобы проверить, какие из них используются в вашей системе), поэтому запрос интерпретируется сервером как неполный, и вы ничего не получаете со стороны ввода. Некоторые серверы довольно прощающие и принимают только \n как разделитель строк, но если вы случайно отправили \n и \r\n неявно (с помощью println), то ваша якобы пустая строка содержит символ \r и больше не будет отображаться как пустая, возможно, запрос о предотвращении отправки сервером ответа.

Поэтому я советую использовать print и отправить правильные разделители строк в явном виде. Кроме того, вам, вероятно, нужно добавить вызов в flush, может быть, потому, что между выходом есть пустая строка - я действительно не знаю, но без вызова flush моя программа все еще висит. Таким образом, чтобы подвести итог, следующее должно работать:

// send request 
out.print("GET /index.html HTTP/1.0\r\n\r\n"); 
out.flush(); 
// read one line of input 
System.out.println("Response from " + line + ": " + in.readLine()); 

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

+0

Вот и все. Большое спасибо! –

2

рекомендую сделать

out.flush(); 

после out.println (...);

Это отправит данные на удаленный сервер. Похоже, что данные никогда не покидают ваш локальный буфер.

I.e.

 Socket socket = new Socket(ip, 80); 
     PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
     BufferedReader in = new BufferedReader(
      new InputStreamReader(socket.getInputStream())); 

     //Send request 
     out.println("GET /index.html HTTP/1.0\n"); 
     out.flush(); 

     //Read one line of input 
     System.out.println("Response from "+line+": "+in.readLine()); 

И если я типа google.com это дает мне:

Response from google.com: HTTP/1.0 200 OK 

Если это не сработает, попробуйте это:

 HttpURLConnection connection = (HttpURLConnection) 
      new URL(url).openConnection(); 
     connection.setRequestMethod("GET"); 
     connection.setDoInput(true); 
     connection.setDoOutput(false); 
     connection.setUseCaches(false); 
     connection.setRequestProperty("Accept", "text/html"); 
     final InputStream is = connection.getInputStream(); 
     // construct BufferredStreamReader from the is 

Отметим, что URL должен как «http://google.com» не просто «google.com»

+0

Эй, я не уверен. Я пробовал это, но это не исправить. – Coffee

+0

По-прежнему не нужно - просто зависает после ввода «www.google.com» и нажмите «Ввод». Я не могу понять. –

+0

Я обновил свой ответ. Оно работает. Также на www.google.com. –

0

У меня было такое же поведение, когда я пробовал код 1-го сообщения (в Windows 8). То же самое со всеми другими способами, предложенными в этой теме.

Тогда я unninstalled мой антивирус (Avast) и все работало ...: $

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