本文介绍了用jcifs定义的超时不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经将responseTimeout和soTimeout设置为15000ms,但是我仍然得到90000ms后超时.

I have set responseTimeout and soTimeout to 15000ms but I still get atimeout after 90000ms.

我在v1.3.18和v1.3.17上进行了测试.

I tested this on v1.3.18 and v1.3.17.

当我不注册jcifs时,发生HttpURLConnection的默认超时15000ms之后正确:

When I don't register jcifs my default timeout for HttpURLConnection occurscorrectly after 15000ms :

connection.setReadTimeout(15000);
connection.setConnectTimeout(15000);

但是当我注册jcifs时,则在90000ms之后发生了超时:

But when I register jcifs then the timout occurs after 90000ms:

System.setProperty("jcifs.smb.client.responseTimeout", "15000");
System.setProperty("jcifs.smb.client.soTimeout", "15000");
jcifs.Config.registerSmbURLHandler();
[...]
connection.setReadTimeout(15000);
connection.setConnectTimeout(15000);

似乎jcifs超时和我的默认超时都被忽略了另一个值.

It seems that the jcifs timeout and my default timeout are both ignored foranother value.

我也直接在Config上尝试过setProperty,但是它没有改变:

I have also tried setProperty directly on Config but it does not change :

jcifs.Config.setProperty("jcifs.smb.client.responseTimeout", "15000");
jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "15000");

推荐答案

(此消息已发布到jcifs论坛,位于 http://thread.gmane.org/gmane.network.samba.java/9554 )

(This message was posted to jcifs forum at http://thread.gmane.org/gmane.network.samba.java/9554)

对我来说,问题是jcifs包装了一个新的HttpURLConnection,因此它将丢失在原始连接上定义的所有设置,例如超时设置.为了证明这一点,我要么使用反射,要么修改库并更改jcifs内部连接,那么超时可以正常工作.

For me the problem is that jcifs wraps a new HttpURLConnection so it loses every settings defined on the original connection, like the timeout settings. To prove this either I use reflection or I modify the library and change jcifs internal connection, then the timeout works fine.

(有关设置jcifs.smb.client.responseTimeout和jcifs.smb.client.soTimeout的信息无效)

(For information setting jcifs.smb.client.responseTimeout and jcifs.smb.client.soTimeout does not work)

首先,我确认jcifs是问题所在:当我使用jcifs.Config.registerSmbURLHandler()时,我的15000ms超时根本不起作用,在30000ms之后连接中断.仅当我删除对registerSmbURLHandler()的调用时,我的15000ms超时才有效.

First, I validate that jcifs is the problem : my timeout of 15000ms does not work at all when I use jcifs.Config.registerSmbURLHandler(), connection breaks after 30000ms. My 15000ms timeout works only if I remove the call to registerSmbURLHandler().

关于该问题,我打开了一个连接(先前已注册了jcifs):

Regarding the problem, I open a connection (with jcifs previously registered) :

URLConnection myConnection = new URL(url).openConnection();

然后,URLStreamHandler创建一个包装的NtlmHttpURLConnection并隐藏真正的HttpURLConnection:

Then the URLStreamHandler creates a wrapping NtlmHttpURLConnection and hides the real HttpURLConnection :

protected URLConnection openConnection(URL url) throws IOException {
    url = new URL(url, url.toExternalForm(),
            getDefaultStreamHandler(url.getProtocol()));
    return new NtlmHttpURLConnection((HttpURLConnection)
            url.openConnection());
}

因此我的超时设置应用于包装器NtlmHttpURLConnection,而不应用于真正打开的URLConnection.所以我的超时没用了:

So my timeout settings are applied to the wrapper NtlmHttpURLConnection, it's not applied to the true opened URLConnection. So my timeout are useless :

myConnection.setReadTimeout(15000);    // applied to the new NtlmHttpURLConnection(wrapped), not the real wrapped one
myConnection.setConnectTimeout(15000); // applied to the new NtlmHttpURLConnection(wrapped), not the real wrapped one

我可以使用两种解决方案来更改包装连接的超时:使用反射或使用固定库.

There are two solutions I can use to change the timeout on the wrapped connection : with reflection or with a fixed library.

通过反射,我访问私有包装的连接并更改私有字段connectTimeout和readTimeout:

With reflection, I access the private wrapped connection and change the private fields connectTimeout and readTimeout :

Class<?> classConnection = myConnection.getClass();

Field privateFieldURLConnection = classConnection.getDeclaredField("connection");
privateFieldURLConnection.setAccessible(true);

URLConnection privateURLConnection = (URLConnection) privateFieldURLConnection.get(myConnection);
Class<?> classURLConnectionPrivate = privateURLConnection.getClass();

Field privateFieldConnectTimeout = classURLConnectionPrivate.getDeclaredField("connectTimeout");
privateFieldConnectTimeout.setAccessible(true);
privateFieldConnectTimeout.setInt(privateURLConnection, 15000);

Field privateFieldReadTimeout = classURLConnectionPrivate.getDeclaredField("readTimeout");
privateFieldReadTimeout.setAccessible(true);
privateFieldReadTimeout.setInt(privateURLConnection, 15000);

或者我修改jcifs库和构造函数NtlmHttpURLConnection():

Or I modify the jcifs library and the constructor NtlmHttpURLConnection() :

public NtlmHttpURLConnection(HttpURLConnection connection) {
    super(connection.getURL());
    this.connection = connection;

    this.connection.setReadTimeout(15000);
    this.connection.setConnectTimeout(15000);

    requestProperties = new HashMap();
}

这篇关于用jcifs定义的超时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-19 13:51