简单的java http客户端没有服务器响应
我正在尝试编写一个简单的Java http客户端,它只打印出一行服务器响应。 我的问题是我得不到服务器的响应。 这是我所拥有的,编译和运行没有明确的错误,它只是在我键入主机名后挂起,例如’www.google.com’:
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’ – 即使这是真的,它仍然会挂起。
我认为我已经能够通过对代码进行少量更改来重现该问题,因此现在它在我的机器上不起作用并且表现出与在您的环境中相同的行为。 我刚刚将out.println
调用更改为更简单的out.print
,并且看,程序在发出请求之后但在最后一次println
调用之前挂起。
据我所知,HTTP请求需要在标题后面提供一个空行,其中行分隔符必须是\r\n
几个字符。 我想你的环境是这样的, println
不会发送正确的行分隔符(你可以检查System.getProperty("line.separator")
来validation你的系统上使用的那些),所以请求被解释由服务器不完整,你在输入端什么也得不到。 有些服务器非常宽容并且只接受\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());
至少,我可以通过这些更改确认程序在我的机器上运行。
我建议做
out.flush();
out.println(…)之后;
这会将数据发送到远程服务器。 看起来数据永远不会离开本地缓冲区。
即
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”
当我尝试第一篇文章的代码(在Windows 8上)时,我有完全相同的行为。 与本主题中提出的所有其他方法相同。
然后我卸载了我的防病毒软件(avast),一切正常……:$