我正在下载网络文件,用的httpwebrequest GetResponse GetResponseStream,整个都能跑通
唯一的问题是 如果服务器不响应我了,就会在stream.read处无限挂起,
无论是设置httpwebrequest 的ReadWriteTimeout (所有能设置的timeout我都设置过了 不生效 会在read处卡住 等待服务器反应)
还是设置stream的ReadTimeout和WriteTimeout都无效,就是一直获取到数据为止,断连的话read就返回0了,但服务器也不断连,就一直拖着。
20分钟也不断,就一直在等待。资源是别人服务器的,所以无法调整服务器端,所以这种情况该怎么处理,很头疼。
有解决方法的话我亲测可用后会给分。
不好意思,刚刚我回答多个问题回答混了(抱歉!)
你试试多线程解决方法:(我不保证成功)
基本思路是:
使用多线程的方法,开启一个新的线程来执行stream.read(),并设置线程的超时时间。
如果线程超时,就会自动结束线程,从而解决无限挂起的问题。
再用一个线程监视就行了。
可以试试以下方法
1,用线程监听,然后用,HttpWebRequest.Abort()结束请求
2,使用HttpWebRequest.BeginGetRequestStream(AsyncCallback, Object)异步请求
3,使用read前用CanRead判断一下,用CanSeek判断一下,CanTimeout,CanWrite也可以试试,或者设置一下steam的ReadTimeout和WriteTimeout
4,使用Read(Byte[], Int32, Int32)每次读取指定的字节,循环读取,这样就可以在循环里增加一个判断,比如循环次数太多,判断返回的文件是恶意的,就终止读取。
摘自一篇实例的思路:
**做个总结,进行远程通信时,在客户程序中,线程在以下情况可能进入阻塞状态:**
请求与服务器建立连接时,即当线程执行Socket的带参数的构造方法,或执行Socket的connect()方法时,会进入阻塞状态,直到连接成功,此线程才从Socket的构造方法或connect()方法返回。
线程从Socket的输入流读入数据时,如果没有足够的数据,就会进入阻塞状态,直到读到了足够的数据,或者到达输入流的末尾,或者出现了异常,才从输入流的read()方法返回或异常中断。输入流中有多少数据才算足够呢?这要看线程执行的read()方法的类型:
1. int read():只要输入流中有一个字节,就算足够。
2. int read(byte[] buff):只要输入流中的字节数目与参数buff数组的长度相同就算足够。
3. String readLine():只要输入流中有一行字符串,就算足够。值得注意的是InputStream类并没有readLine()方法,在过滤流BufferedReader类中才有此方法。
线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据,或者出现异常,才从输出流的write()方法返回或异常中断。
当调用Socket的setSoLinger()方法设置了关闭Socket的延迟时间,那么当线程执行Socket的close()方法时,会进入阻塞状态,直到底层Socket发送完所有剩余数据,或者超过了setSoLinger()方法设置的延迟时间,才从close()方法返回。
在服务器程序中,线程在以下情况可能会进入阻塞状态:
线程执行ServerSocket的accept()方法,等待客户的连接,直到接收到了客户连接,才从accept()方法返回。
线程从Socket的输入流读入数据时, 如果输入流没有足够的数据,就会进入阻塞状态。
线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据,或者出现异常,才从输出流的write()方法返回或异常中断。
###解决方案
---
1, 通过setTimeout可以解决问题
```java
//设置connection timeout为3秒
connection.setConnectionTimeout(3 * 1000)
//设置read timeout为5秒
connection.setReadTimeout(5 * 1000)
2,通过一个connection的监控线程,查询定时清除掉已经expired或者idle的链接。
<div class="se-preview-section-delimiter"></div>
```java
public static class IdleConnectionMonitorThread extends Thread {
private final HttpClientConnectionManager connMgr;
private volatile boolean shutdown;
public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
super();
this.connMgr = connMgr;
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// Close expired connections
connMgr.closeExpiredConnections();
// Optionally, close connections
// that have been idle longer than 30 sec
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ex) {
// terminate
}
}
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
为了避免在Stream.Read方法处无限挂起,可以使用HttpWebRequest.GetResponse方法的重载版本,它具有超时参数。例如:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 10000; // 10 seconds
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
这将设置请求的超时时间为10秒。如果服务器在10秒内未响应,则会引发超时异常。
此外,还可以使用WebException类的Status属性来检测超时。例如:
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 10000; // 10 seconds
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
// The request timed out
}
}
在调用 HttpWebRequest.GetResponse() 方法时,可以将其包装在 try-catch 语句中,并在捕获 WebException 异常时进行处理。WebException 异常表示在进行 HTTP 求时发生错误。可以使用 WebException.Status 属性检查具体的错误状态。
例如可以使用以下代码来处理服务器不响应的情况:
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// 处理响应
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
// 处理超时
}
else if (ex.Status == WebExceptionStatus.ConnectFailure)
{
// 处理连接失败
}
else
{
// 处理其他异常
}
}
还可以使用 WebException.Response 属性获取服务器返回的响应,以便进一步处理。
此外还可以在创建 HttpWebRequest 对象时设置超时时间。例如使用 HttpWebRequest.Timeout 属性可以设置整个求的超时时间,使用 HttpWebRequest.ReadWriteTimeout 属性可以设置读写流的超时时间。
在调用 HttpWebRequest.GetResponse() 方法之前,还可以使用 HttpWebRequest.Abort() 方法中止求。
在调用 HttpWebRequest.GetResponse() 方法时,可以将其包装在 try-catch 语句中,并在捕获 WebException 异常时进行处理。WebException 异常表示在进行 HTTP 求时发生错误。可以使用 WebException.Status 属性检查具体的错误状态。
例如可以使用以下代码来处理服务器不响应的情况:
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// 处理响应
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
// 处理超时
}
else if (ex.Status == WebExceptionStatus.ConnectFailure)
{
// 处理连接失败
}
else
{
// 处理其他异常
}
}
可以使用 WebException.Response 属性获取服务器返回的响应,以便进一步处理。
还可以在创建 HttpWebRequest 对象时设置超时时间。例如使用 HttpWebRequest.Timeout 属性可以设置整个求的超时时间,使用 HttpWebRequest.ReadWriteTimeout 属性可以设置读写流的超时时间。
在调用 HttpWebRequest.GetResponse() 方法之前,还可以使用 HttpWebRequest.Abort() 方法中止求。
望采纳。
NetworkStream.Read会挂起/阻止的原因是什么
借鉴下
https://qa.1r1g.com/sf/ask/487077881/