HTTP首包时延问题 200分急求高手解答!顶者就有分。

ladybirds2008 2012-05-07 09:54:10
我是linux的服务器上 部署的java程序,公网客户端访问系统,在服务器上测试 www.189.cn,www.youku.com网站都正常,而且速度还挺快,测试结果如下:
-bash-3.2$ wget 'www.189.cn'
--2012-05-07 09:17:32-- http://www.189.cn/
正在解析主机 www.189.cn... 118.85.207.18
Connecting to www.189.cn|118.85.207.18|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:41881 (41K) [text/html]
Saving to: `index.html.13'

100%[==========================================================================================>] 41,881 217K/s in 0.2s

2012-05-07 09:17:32 (217 KB/s) - `index.html.13' saved [41881/41881]

-bash-3.2$ wget 'www.youku.com'
--2012-05-07 09:19:26-- http://www.youku.com/
正在解析主机 www.youku.com... 121.9.204.234
Connecting to www.youku.com|121.9.204.234|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:390160 (381K) [text/html]
Saving to: `index.html.14'

100%[==========================================================================================>] 390,160 120K/s in 3.2s

2012-05-07 09:19:29 (120 KB/s) - `index.html.14' saved [390160/390160]

但是为啥我java程序就不能获取到这2个网站的首包时延的,获取首包时延代码如下:希望高手给予解答,是服务器环境问题呢还是代码问题 还是其网站端口 协议不对呢?
String ip = "1.1.1.1";//此处为dns解析出来的网站IP地址
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, 80), 15000);
boolean autoflush = true;
PrintWriter out = new PrintWriter(socket.getOutputStream(), autoflush);
BufferedReader in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
// send an HTTP request to the web server
out.println("GET / HTTP/1.1");
out.println("Accept: */*");
out.println("User-Agent: cdut-boy");
out.println("Host: " + load_url);//此处为网站网址
out.println();
logger.info("获取HTTP页面首包时延发包结束,网站网址:load_url=" + load_url);
boolean loop = true;
while (loop)
{
if (in.ready())//此处 优酷 189 从来就读取不到首包,高手解答
{
//..........do something...under...
loop = false;
}
}
...全文
780 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuxiaowei 2014-06-19
  • 打赏
  • 举报
回复
引用 22 楼 flying_lanying 的回复:
[quote=引用 21 楼 ladybirds2008 的回复:] 问题解决了 是因为socket出现阻塞 导致,前台客户端请求超时时候 关闭,后台出现了阻塞。。。 感谢各位!特别鸣谢idh911的解答和帮助。。。
可以告知一下你是如何解决这个最终问题的嘛?因为我也遇到这种情况,我需要获取的有首包时延、DNS时延、TCP时延,目前还不知道tcp时延如何解决~首包时延与DNS时延会出现有些时间超长[/quote] 最后用了什么解决方法?
Java大胖纸 2013-05-13
  • 打赏
  • 举报
回复
引用 21 楼 ladybirds2008 的回复:
问题解决了 是因为socket出现阻塞 导致,前台客户端请求超时时候 关闭,后台出现了阻塞。。。 感谢各位!特别鸣谢idh911的解答和帮助。。。
可以告知一下你是如何解决这个最终问题的嘛?因为我也遇到这种情况,我需要获取的有首包时延、DNS时延、TCP时延,目前还不知道tcp时延如何解决~首包时延与DNS时延会出现有些时间超长
ladybirds2008 2012-05-07
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
我去掉BufferedReader测试了下,貌似效果还行:


Java code


public class SiteSpeed {

public static void main(String[] args) throws Exception {
String url = "www.youku.com";

Socket soc……
[/Quote]还是不行啊,真郁闷啊。。。除了代码的原因外,有没有可能其它原因呢,,请详述下呢。
MiceRice 2012-05-07
  • 打赏
  • 举报
回复
我去掉BufferedReader测试了下,貌似效果还行:


public class SiteSpeed {

public static void main(String[] args) throws Exception {
String url = "www.youku.com";

Socket socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress.getByName(url), 80), 15000);
PrintWriter out = new PrintWriter(socket.getOutputStream());
InputStream in = socket.getInputStream();
// send an HTTP request to the web server
out.println("GET / HTTP/1.1");
out.println("Accept: */*");
out.println("User-Agent: cdut-boy");
out.println("Host: " + url);//此处为网站网址
out.println();
out.flush();
long timer = System.currentTimeMillis();
log("获取HTTP页面首包时延发包结束,网站网址:" + url);

in.read();
timer = System.currentTimeMillis() - timer;
log("获取HTTP页面首包时延:" + timer + "ms");

timer = System.currentTimeMillis();
while (in.read(new byte[8192]) > 0){}
timer = System.currentTimeMillis() - timer;
log("全部下载完毕:" + timer + "ms");
}

private static void log(Object msg) {
System.out.println(msg);
}

}


获取HTTP页面首包时延发包结束,网站网址:www.youku.com
获取HTTP页面首包时延:21ms
全部下载完毕:2338ms
MiceRice 2012-05-07
  • 打赏
  • 举报
回复
其实问题在于 ready() 这个函数,在InputStream中并没有定义,是在 中才有的,而且本身是借助:sun.nio.cs.StreamDecoder 来实现的。所以具体是什么原因导致的,需要花时间研究下。API只是说,它会检查缓冲区中是否有数据,如果有才返回ready()

“获取首包时延 超出需求时限的话 我不好控制”
——嗯,确实会存在卡的问题,这种情况下,可能你需要采用NIO模型来开发,而不是IO模型;NIO提供无阻塞的各种实现。

“用in.readLine()这个时延怎么获得的为60984多”
——我想了下,可能是因为包装了BufferedReader的原因,它要先Buffer一段内容;这种情况下,需要直接使用 socket.getInputStream(),不做任何包装,然后直接 read 1个字节就好了。但是 60秒也太夸张了吧。。。感觉是服务器出错了吧?
cseu 2012-05-07
  • 打赏
  • 举报
回复
我拿你的代码试过了,没问题的。不管是in.ready(),in.readLine()都可以的,延时都在10ms左右。
估计是你的网络问题
ladybirds2008 2012-05-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
所谓首包延时,也就是自你发送完请求后,到服务器返回给你第一个信息中间的耗时。是这个意思吧?

我建议考虑换个思路:
1、在out.println();之后,记录 long timer = System.currentTimeMillis();
2、然后直接in.readLine(),再记录下 timer = System.currentTimeMillis() - timer;

这个……
[/Quote]而且 对于 获取首包时延 超出需求时限的话 我不好控制,所以用in.ready()去循环读取如果超出时限比如5秒,就直接跳出返回数据,进行下一个网址的首包测试,不然用in.readyLine()会卡到这的,用户感知不好。。我的疑问是为啥和用wget测试的 或 ping 测试的有差异呢,首包为什么这么慢呢或有时候直接就读取不到呢
ladybirds2008 2012-05-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
所谓首包延时,也就是自你发送完请求后,到服务器返回给你第一个信息中间的耗时。是这个意思吧?

我建议考虑换个思路:
1、在out.println();之后,记录 long timer = System.currentTimeMillis();
2、然后直接in.readLine(),再记录下 timer = System.currentTimeMillis() - timer;

这个……
[/Quote]是这样的,原来我是in.ready(),但是用in.readLine()这个时延怎么获得的为60984多 ,相当于60多秒哦,还是和我用wget 测试的有差异啊 。。
MiceRice 2012-05-07
  • 打赏
  • 举报
回复
所谓首包延时,也就是自你发送完请求后,到服务器返回给你第一个信息中间的耗时。是这个意思吧?

我建议考虑换个思路:
1、在out.println();之后,记录 long timer = System.currentTimeMillis();
2、然后直接in.readLine(),再记录下 timer = System.currentTimeMillis() - timer;

这个其实相当于你的首包延时,片段如下:

out.println("Host: " + load_url);//此处为网站网址
out.println();
out.flush();
long timer = System.currentTimeMillis();
logger.info("获取HTTP页面首包时延发包结束,网站网址:load_url=" + load_url);
String lineFirst = in.readLine();
timer = System.currentTimeMillis() - timer;
logger.info("获取HTTP页面首包时延:" + timer + "ms");
尹天奇 2012-05-07
  • 打赏
  • 举报
回复
真的很高深。。。顶下!
a1018615265 2012-05-07
  • 打赏
  • 举报
回复
web开发学到这程度,不一般了
ladybirds2008 2012-05-07
  • 打赏
  • 举报
回复
求高人 解答下呢、、、
zuxianghuang 2012-05-07
  • 打赏
  • 举报
回复
这个不清楚,顶一下
ladybirds2008 2012-05-07
  • 打赏
  • 举报
回复
问题解决了 是因为socket出现阻塞 导致,前台客户端请求超时时候 关闭,后台出现了阻塞。。。
感谢各位!特别鸣谢idh911的解答和帮助。。。
MiceRice 2012-05-07
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]
同样其它的网站 都是很快的,为什么 189 youku 首包时延 就很大呢。。。
求 高手啊。。
[/Quote]

用IE9,F12调出IE自带监视器,看看对youku的统计情况吧。
ladybirds2008 2012-05-07
  • 打赏
  • 举报
回复
同样其它的网站 都是很快的,为什么 189 youku 首包时延 就很大呢。。。
求 高手啊。。
watermarkmms 2012-05-07
  • 打赏
  • 举报
回复
因为你在服务器上的测试时用wget命令,而你的代码是用socket连接,协议都不一样了
watermarkmms 2012-05-07
  • 打赏
  • 举报
回复
会不会是socket流阻塞的问题?不能用其他方式么?比如httpclient
lyf520llp 2012-05-07
  • 打赏
  • 举报
回复
能够看懂一部分 纯属高手 新手报到
tomcatlee 2012-05-07
  • 打赏
  • 举报
回复
不知道你要干嘛,下面代码仅作参考:
package com.tom.labs;

import java.net.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.io.*;

public class JavaHttp {
public static void main(String[] args) throws Exception {
File data = new File("D:\\in.txt");
File result = new File("D:\\out.txt");
FileOutputStream out = new FileOutputStream(result);
OutputStreamWriter writer = new OutputStreamWriter(out);
Reader reader = new InputStreamReader(new FileInputStream(data));
//postData(reader,new URL("http://google.com"),writer);//Not working
postData(reader,new URL("http://yahoo.com"),writer);//Not working
//sendGetRequest("http://google.com/search", "q=Hello");//Works properly
head("http://google.com");
}

public static String sendGetRequest(String endpoint,
String requestParameters) {
String result = null;
if (endpoint.startsWith("http://")) {
// Send a GET request to the servlet
try {
// Send data
String urlStr = endpoint;
if (requestParameters != null && requestParameters.length() > 0) {
urlStr += "?" + requestParameters;
}
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(result);
return result;
}

/**
* Reads data from the data reader and posts it to a server via POST
* request. data - The data you want to send endpoint - The server's address
* output - writes the server's response to output
*
* @throws Exception
*/
public static void postData(Reader data, URL endpoint, Writer output)
throws Exception {
HttpURLConnection urlc = null;
try {
urlc = (HttpURLConnection) endpoint.openConnection();
try {
urlc.setRequestMethod("POST");
} catch (ProtocolException e) {
throw new Exception(
"Shouldn't happen: HttpURLConnection doesn't support POST??",
e);
}
urlc.setDoOutput(true);
urlc.setDoInput(true);
urlc.setUseCaches(false);
urlc.setAllowUserInteraction(false);
urlc.setRequestProperty("Content-type", "text/xml; charset=UTF-8");
OutputStream out = urlc.getOutputStream();
try {
Writer writer = new OutputStreamWriter(out, "UTF-8");
pipe(data, writer);
writer.close();
} catch (IOException e) {
throw new Exception("IOException while posting data", e);
} finally {
if (out != null)
out.close();
}
InputStream in = urlc.getInputStream();
try {
Reader reader = new InputStreamReader(in);
pipe(reader, output);
reader.close();
} catch (IOException e) {
throw new Exception("IOException while reading response", e);
} finally {
if (in != null)
in.close();
}
} catch (IOException e) {
e.printStackTrace();
throw new Exception("Connection error (is server running at "
+ endpoint + " ?): " + e);
} finally {
if (urlc != null)
urlc.disconnect();
}
}

static void head(String endpoint){
URL url;
try {
url = new URL(endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// conn.setDoOutput(true);
conn.setRequestMethod("HEAD");
Map<String, List<String>> headerMap = conn.getHeaderFields();
Iterator<String> iterator = headerMap.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
List<String> values = headerMap.get(key);
System.out.println(key + ":" + values.toString());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Pipes everything from the reader to the writer via a buffer
*/
private static void pipe(Reader reader, Writer writer) throws IOException {
char[] buf = new char[1024];
int read = 0;
while ((read = reader.read(buf)) >= 0) {
writer.write(buf, 0, read);
}
writer.flush();
}


}

81,091

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧