检测HTTP请求的结束(Java套接字)最简单的方法是什么?
我必须使用Java套接字发送和接收HTTP请求(我必须!)。因此,我正在寻找一种考虑检测HTTP请求的结束(Java套接字)最简单的方法是什么?,java,sockets,Java,Sockets,我必须使用Java套接字发送和接收HTTP请求(我必须!)。因此,我正在寻找一种考虑内容长度和传输编码的解决方案:分块,等等。。。决定HTTP请求何时结束 以下是我迄今为止提出的一个例子: public String getWebpage() { try{ _out.print("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"); _out.flush();
内容长度
和传输编码的解决方案:分块
,等等。。。决定HTTP请求何时结束
以下是我迄今为止提出的一个例子:
public String getWebpage()
{
try{
_out.print("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n");
_out.flush();
String fullRequest = "";
String line = null;
while (( line = _in.readLine()) != null)
{
fullRequest += line + "\r\n";
if(isFullRequest(fullRequest))
{
System.out.println(fullRequest);
return fullRequest;
}
}
}catch(Exception e){}
return null;
}
private boolean isFullRequest(String request)
{
return request.contains("\r\n\r\n") //Make sure we have the headers
&& request.contains("</html>"); //Make sure we have the html
}
公共字符串getWebpage()
{
试一试{
_out.print(“GET/HTTP/1.1\r\nHost:www.google.com\r\n\r\n”);
_out.flush();
字符串fullRequest=“”;
字符串行=null;
而((line=_in.readLine())!=null)
{
fullRequest+=行+“\r\n”;
if(isFullRequest(fullRequest))
{
系统输出打印项次(完整请求);
返回完整请求;
}
}
}捕获(例外e){}
返回null;
}
私有布尔isFullRequest(字符串请求)
{
return request.contains(“\r\n\r\n”)//请确保我们有标头
&&request.contains(“”;//确保我们有html
}
我的isFullRequest()
方法是检测请求结束的一种非常便宜的方法,但不可靠
我想问的是,Java中是否已经包含了一个类或方法,可以完全满足我的需要,而不是重新发明轮子,花费无数的时间进行调试?没有额外的不必要的jar依赖项?如果您不想使用现有的HTTP库,那么只发出HTTP/1.0请求就更容易了,这样您就不会得到分块响应(分块仅为HTTP/1.1定义)。也不要使用keep-alive,这在HTTP/1.1中是隐式的,但在HTTP/1.0中不是。总之,您的请求如下所示:
GET /page HTTP/1.0
Host: hostname
然后只需读取响应,直到数据结束。由于HTTP/1.0默认情况下关闭了keep alive,服务器将在响应完成后关闭连接,并且由于HTTP/1.0不支持分块,您也不必担心这一点。您可以使用它来读取分块响应。这样,您就不必担心检测到请求的结束
URL url = new URL(urlStr);
HttpURLConnection uc = (HttpURLConnection)url.openConnection();
InputStream in = uc.getInputStream();
byte[] b=new byte[512*1024];
int len;
OutputStream out = new FileOutputStream(f);
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
out.flush();
out.close();
in.close();
如果您想获得内容长度,可以尝试:
long contentLength = uc.getContentLengthLong()
只有当内容长度
标题已知时,它才会起作用
如果不知道,还有另一种方法(虽然不是我最喜欢的…)。只需阅读一次流即可了解内容长度。
我在一个项目中使用了它,在下载页面内容时必须绘制进度条
long max = uc.getContentLengthLong();
if(max==-1){
max=0;
if(in.markSupported()){
in.mark(1000000000); //max nb of bytes to be read
while((len=in.read(b))!=-1){
max+=len;
}
in.reset();
}
}
非常感谢。这种方法暂时解决了我的问题,但可能也不太可靠,因为从长远来看,它可能会导致一些问题。。(如果存在HTTP/1.0服务器不兼容或Bot检测或保护等问题)如果您希望看起来和行为更像一个真正的浏览器,那么它要复杂得多,因为您不仅需要支持HTTP/1.1和分块,还需要支持gzip和deflate内容编码。即使这样,由于缺少JavaScript,没有加载CSS、图像、字体等包含的资源,没有发送回cookie等等,也很容易将您的请求与桌面浏览器区分开来。