﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava--随笔分类-io,tcp</title><link>http://www.blogjava.net/leekiang/category/34765.html</link><description>MDA/MDD/TDD/DDD/DDDDDDD</description><language>zh-cn</language><lastBuildDate>Sun, 18 Apr 2010 22:13:49 GMT</lastBuildDate><pubDate>Sun, 18 Apr 2010 22:13:49 GMT</pubDate><ttl>60</ttl><item><title>Adding Socket Timeout to java.net.URLConnection (JDK 1.2)</title><link>http://www.blogjava.net/leekiang/archive/2010/04/14/318278.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Wed, 14 Apr 2010 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2010/04/14/318278.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/318278.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2010/04/14/318278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/318278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/318278.html</trackback:ping><description><![CDATA[
		<h1 style="">Adding Socket Timeout to java.net.URLConnection (JDK 1.2)</h1>
		<h2>found a bug , see "connected = true;" in  public void connect() 
throws IOException {</h2>
		<hr />
		<h1>Note: 05/11/01 Sam Found a patch for borland</h1>
		<p>As I got the email:</p>
		<p>Just writing to inform you theis patch for 1.3 works with the 1.3 
shipped with borland JBuilder 4 
(not sure which excat version it is)</p>
		<p>the only problems I had where that the code was a bit messed up,  
following are the changes made to it to make it work. </p>
		<pre>
				<br />  public void SetTimeout(int i) <br />    throws SocketException <br />  { <br />    this.timeout = i; // Should be i not -1   &lt;------------ERROR <br />    serverSocket.setSoTimeout(i) ; <br />  } <br /><br />  public boolean parseHTTP(MessageHeader header, ProgressEntry entry) <br />    throws java.io.IOException <br />  { <br />    if( this.timeout != -1 ) { <br />      try { <br />        serverSocket.setSoTimeout(timeout) ; // should be timeout not i &lt;---------------ERROR <br />      } catch( SocketException e ) { <br />        throw new java.io.IOException("unable to set socket timeout!") ; <br />      } <br />    } <br /><br />    return super.parseHTTP(header, entry) ; <br />  } <br />Sam <br /></pre>
		<p>Under JDK 1.3, which is HTTP 1.1 compatible, the 
InterruptedIOException gets caught by 
the socket I/O routines and ignored.  input is read in "chunks". I 
debugged the existing code under 1.3, the Timeout is getting set 
properly etc.,
but the exception gets caught in the underlying I/O routines, which have
 a single
retry if any IOExceptions are thrown.  Thanks a lot Sun....</p>
		<h1>3/22/01: Patch for JDK 1.3 unverified</h1>
		<p>Patch code for JDK 1.3 from Matt Ho (unverified)</p>
		<pre>
				<br />----[ snip ]----<br /><br />import sun.net.www.MessageHeader ;<br />import sun.net.ProgressEntry ;<br /><br />.<br />.<br />.<br /><br />  private int timeout = -1 ;<br /><br />  public void SetTimeout(int i)<br />    throws SocketException<br />  {<br />    this.timeout = -1 ;<br />    serverSocket.setSoTimeout(i) ;<br />  }<br /><br />  public boolean parseHTTP(MessageHeader header, ProgressEntry entry)<br />    throws java.io.IOException<br />  {<br />    if( this.timeout != -1 ) {<br />      try {<br />        serverSocket.setSoTimeout(i) ;<br />      } catch( SocketException e ) {<br />        throw new java.io.IOException("unable to set socket timeout!") ;<br />      }<br />    }<br /><br />    return super.parseHTTP(header, entry) ;<br />  }<br /><br />----[ snip ]----<br /><br /></pre>
		<h1>On with the rest of the stuff</h1>
		<p>The BSD socket API supports a timeout option (the option is 
SO_TIMEOUT), which is also supported in java.net.socket.  
Unfortunately, java.net.URLConnection does not expose the underlying 
socket.  So if you have a URL connection that attempts to 
connect to a dead URL (i.e., the URL is well formed and exists but the 
site is down), the socket will eventually timeout using the
operating system's default timeout (420 seconds on Win NT).  The timeout
 is a very long time, e.g., for spiders or URL checking.</p>
		<p>The following files illustrate a technique to introduce a socket 
timeout to URL connection, based upon the actual java 
source code itself (see the open source community licensing at <a href="http://www.javasoft.com/">JavaSoft</a>).</p>
		<h2>The Base classes, or URLConnection internals</h2>
		<p>Java's implementation of networking is protocol independent, as well 
as object oriented.  Therefore the implementation is not as 
straightfoward
as one might imagine.</p>
		<p>URLConnection relies upon several internal classes using a 
client/server model as well as a "factory" design pattern. The client's 
base class 
is  <i>sun.net.www.http.HttpClient</i>.  This class is extended for the 
purpose of exposing the socket.</p>
		<p>The default factory is <i>URLStreamHandlerFactory</i>, which 
indirectly "handles" the creation of an HTTP client by instantiating 
a class that is specific to the HTTP protocol: <i>sun.net.www.protocol.http.Handler</i>.
  The handler actually creates the client.</p>
		<p>In practice, the factory is only necessary to mimic java's 
implementation, but only the Handler is really needed.</p>
		<h2>Derived Classes</h2>
		<p>We derive 4 classes so as to preserve the symmetry with the java 
source code:</p>
HttpURLConnectionTimeout extends 
sun.net.www.protocol.http.HttpURLConnection<br /> 
HttpTimeoutHandler extends sun.net.www.protocol.http.Handler<br />
HttpTimeoutFactory implements java.net.URLStreamHandlerFactory<br />
HttpClientTimeout extends sun.net.www.http.HttpClient<br /><p>On with the source code.</p><br /><h2>HttpURLConnectionTimeout</h2><pre>// whatever package you want<br />import sun.net.www.http.HttpClient;<br />import java.net.*;<br />import java.io.*;<br />public class HttpClientTimeout extends HttpClient<br />{<br />    public HttpClientTimeout(URL url, String proxy, int proxyPort) throws IOException<br />	{<br />		super(url, proxy, proxyPort);<br />	}<br /><br />    public HttpClientTimeout(URL url) throws IOException<br />	{<br />		super(url, null, -1);<br />    }<br /><br />	public void SetTimeout(int i) throws SocketException { <br />    	serverSocket.setSoTimeout(i); <br />    } <br /><br />    /* This class has no public constructor for HTTP.  This method is used to<br />     * get an HttpClient to the specifed URL.  If there's currently an<br />     * active HttpClient to that server/port, you'll get that one.<br />	 *<br />	 * no longer syncrhonized -- it slows things down too much<br />	 * synchronize at a higher level<br />     */<br />    public static HttpClientTimeout GetNew(URL url)  <br />    throws IOException {<br />	/* see if one's already around */<br />	HttpClientTimeout ret = (HttpClientTimeout) kac.get(url);<br />	if (ret == null) {<br />	    ret = new HttpClientTimeout (url);  // CTOR called openServer()<br />	} else {<br />	    ret.url = url;<br />	}<br />	// don't know if we're keeping alive until we parse the headers<br />	// for now, keepingAlive is false<br />	return ret;<br />    }<br /><br />	public void Close() throws IOException<br />	{<br />		serverSocket.close();<br />	}<br /><br />	public Socket GetSocket()<br />	{<br />		return serverSocket;<br />	}<br /><br /><br />}<br /></pre><br /><h2>HttpTimeoutFactory</h2><pre>import java.net.*;<br /><br />public class HttpTimeoutFactory implements URLStreamHandlerFactory<br />{<br />	int fiTimeoutVal;<br />	public HttpTimeoutFactory(int iT) { fiTimeoutVal = iT; }<br />	public URLStreamHandler createURLStreamHandler(String str)<br />	{<br />		return new HttpTimeoutHandler(fiTimeoutVal); <br />	}<br /><br />}<br /></pre><br /><h2>HttpTimeoutHandler</h2><pre>import java.net.*;<br />import java.io.IOException;<br /><br />public class HttpTimeoutHandler extends sun.net.www.protocol.http.Handler<br />{<br />	int fiTimeoutVal;<br />	HttpURLConnectionTimeout fHUCT;<br />	public HttpTimeoutHandler(int iT) { fiTimeoutVal = iT; }<br /><br />    protected java.net.URLConnection openConnection(URL u) throws IOException {<br />		return fHUCT = new HttpURLConnectionTimeout(u, this, fiTimeoutVal);<br />    }<br /><br />    String GetProxy() { return proxy; }		// breaking encapsulation<br />    int GetProxyPort() { return proxyPort; }    // breaking encapsulation<br /><br />	public void Close() throws Exception <br />	{<br />		fHUCT.Close();<br />	}<br /><br />	public Socket GetSocket()<br />	{<br />		return fHUCT.GetSocket();<br />	}<br />}<br /></pre><br /><h2>HttpURLConnectionTimeout</h2><pre>import java.net.*;<br />import java.io.*;<br />import sun.net.www.http.HttpClient;<br /><br />public class HttpURLConnectionTimeout extends sun.net.www.protocol.http.HttpURLConnection<br />{<br />	int fiTimeoutVal;<br />    HttpTimeoutHandler fHandler;<br />	HttpClientTimeout fClient;<br />  	public HttpURLConnectionTimeout(URL u, HttpTimeoutHandler handler, int iTimeout) throws IOException<br />	{   <br />    	super(u, handler);<br />		fiTimeoutVal = iTimeout;<br />	}<br /><br />	public HttpURLConnectionTimeout(URL u,  String host, int port) throws IOException<br />	{  <br />    	super(u, host, port);<br />	}<br /><br />    public void connect() throws IOException {<br />	if (connected) {<br />	    return;<br />	}<br />	try {<br />	    if ("http".equals(url.getProtocol()) /* &amp;&amp; !failedOnce &lt;- PRIVATE */ ) {<br />		// for safety's sake, as reported by KLGroup<br />		synchronized (url)<br />		{<br />			http = HttpClientTimeout.GetNew(url);<br />		}<br />		fClient = (HttpClientTimeout)http;<br />   		((HttpClientTimeout)http).SetTimeout(fiTimeoutVal);<br />	    } else {<br />		// make sure to construct new connection if first<br />		// attempt failed<br />		http = new HttpClientTimeout(url, fHandler.GetProxy(), fHandler.GetProxyPort());<br />	    }<br />	    ps = (PrintStream)http.getOutputStream();<br />	} catch (IOException e) {<br />	    throw e;  }<br />		// this was missing from the original version<br />		connected = true;<br />	}<br /><br />    /**<br />     * Create a new HttpClient object, bypassing the cache of<br />     * HTTP client objects/connections.<br />     *<br />     * @param url	the URL being accessed<br />     */<br />    protected HttpClient getNewClient (URL url)<br />    throws IOException {<br />		HttpClientTimeout client = new HttpClientTimeout (url, (String)null, -1);<br />		try {<br />		client.SetTimeout(fiTimeoutVal);<br />		} catch (Exception e) <br />		{ System.out.println("Unable to set timeout value"); }<br />	return (HttpClient)client; <br />    }<br /><br />    /**<br />     * opens a stream allowing redirects only to the same host.<br />     */<br />    public static InputStream openConnectionCheckRedirects(URLConnection c)<br />	throws IOException<br />    {<br />        boolean redir;<br />        int redirects = 0;<br />        InputStream in = null;<br /><br />        do {<br />            if (c instanceof HttpURLConnectionTimeout) {<br />                ((HttpURLConnectionTimeout) c).setInstanceFollowRedirects(false);<br />            }<br /><br />            // We want to open the input stream before<br />            // getting headers, because getHeaderField()<br />            // et al swallow IOExceptions.<br />            in = c.getInputStream();<br />            redir = false;<br /><br />            if (c instanceof HttpURLConnectionTimeout) {<br />                HttpURLConnectionTimeout http = (HttpURLConnectionTimeout) c;<br />                int stat = http.getResponseCode();<br />                if (stat &gt;= 300 &amp;&amp; stat &lt;= 305 &amp;&amp;<br />                        stat != HttpURLConnection.HTTP_NOT_MODIFIED) {<br />                    URL base = http.getURL();<br />                    String loc = http.getHeaderField("Location");<br />                    URL target = null;<br />                    if (loc != null) {<br />                        target = new URL(base, loc);<br />                    }<br />                    http.disconnect();<br />                    if (target == null<br />                        || !base.getProtocol().equals(target.getProtocol())<br />                        || base.getPort() != target.getPort()<br />                        || !HostsEquals(base, target)<br />                        || redirects &gt;= 5)<br />                    {<br />                        throw new SecurityException("illegal URL redirect");<br />		    }<br />                    redir = true;<br />                    c = target.openConnection();<br />                    redirects++;<br />                }<br />            }<br />        } while (redir);<br />        return in;<br />    }<br /><br />    // Same as java.net.URL.hostsEqual<br /><br /><br />	static boolean HostsEquals(URL u1, URL u2) <br />    { <br />        final String h1 = u1.getHost();<br />        final String h2 = u2.getHost();<br /><br />        if (h1 == null) {<br />            return h2 == null;<br />        } else if (h2 == null) {<br />            return false;<br />        } else if (h1.equalsIgnoreCase(h2)) {<br />            return true;<br />        }<br />            // Have to resolve addresses before comparing, otherwise<br />            // names like tachyon and tachyon.eng would compare different<br />        final boolean result[] = {false};<br /><br />        java.security.AccessController.doPrivileged(<br />            new java.security.PrivilegedAction() {<br />            public Object run() {<br />            try {<br />                InetAddress a1 = InetAddress.getByName(h1);<br />                InetAddress a2 = InetAddress.getByName(h2);<br />                result[0] = a1.equals(a2);<br />            } catch(UnknownHostException e) {<br />            } catch(SecurityException e) {<br />            }<br />            return null;<br />            }<br />        });<br /><br />        return result[0];<br />	}<br /><br />	void Close() throws Exception<br />	{<br />		fClient.Close();<br />	}<br /><br />	Socket GetSocket()<br />	{<br />		return fClient.GetSocket();<br />	}<br />}<br /><br /></pre><h2>Sample Usage #1</h2><pre>import java.net.*;<br />public class MainTest<br />{<br /><br />	public static void main(String args[])<br />	{<br />	    int i = 0;<br />    	try {<br />			URL theURL = new URL((URL)null, "http://www.snowball.com", new HttpTimeoutHandler(150)); // timeout value in milliseconds<br /><br />	        // the next step is optional<br />			theURL.setURLStreamHandlerFactory(new HttpTimeoutFactory(150));<br /><br /><br />			URLConnection theURLconn = theURL.openConnection();<br />	        theURLconn.connect();<br />    	    i = theURLconn.getContentLength();<br />        }<br />        catch (InterruptedIOException e)<br />        {<br />        	System.out.println("timeout on socket");<br />        }<br />        System.out.println("Done, Length:" + i);<br />	}<br />}<br /></pre><br /><h2 style="">Sample Usage #2</h2><pre>		try<br />		{<br />			HttpTimeoutHandler xHTH = new HttpTimeoutHandler(10);	// timeout value in milliseconds<br />	        URL theURL = new URL((URL)null, "http://www.javasoft.com", xHTH);<br />	        HttpURLConnection theUC = theURL.openConnection();<br />			.<br />			.<br />			.<br />		}<br />		catch (InterruptedIOException e)<br />		{<br />			// socket timed out<br /><br />		}<br /></pre><br /><p>Some remarks: this code is thread safe.</p><p>More to come</p><p>来源:http://www.logicamente.com/sockets.html</p><p>     http://www.edevs.com/java-programming/15068/</p><p><br /></p><p>Thanks Felipe!</p><p style="">If I understand information at 
http://www.logicamente.com/sockets.html correctly there are 2 problems 
with timeout when using HttpURLConnection in JDK 1.3:</p><p style="">1. 
HttpURLConnection does not allow changing the default timeout that is in
 order of few minutes.</p><p>2. If actual HTTP stream is chunked then 
HttpURLConnection ignores even the default timeout and tries to read 
what it perceives as a continued stream resulting in indefinite read 
wait.</p><p>The patch shown at the above URL, consisting of subclassing 
of 4 system classes (1 from java.net... and 3 from sun.net.www...), is 
aimed to resolve problem 1 above but does not help in problem 2.</p><p>My
 main problem is to have timeout when reading chunked stream (system 
default timeout will be ok to beginning with) and therefore the question
 is if this bug has been corrected in later versions of JDK? Thanks.</p><p>-----<br /></p><p style="">I have seen much chat about this "problem", that is 
setSoTimeout not available or not working properly.</p><p>how about you 
write your own Timer (resettable) or 1.4 has Timer class</p><p>you just 
reset it anytime you detect network activity and close the Socket if the
 Timer finishes its cycle?</p><img src ="http://www.blogjava.net/leekiang/aggbug/318278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2010-04-14 17:09 <a href="http://www.blogjava.net/leekiang/archive/2010/04/14/318278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HttpURLConnection timeout solution</title><link>http://www.blogjava.net/leekiang/archive/2010/04/14/318274.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Wed, 14 Apr 2010 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2010/04/14/318274.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/318274.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2010/04/14/318274.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/318274.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/318274.html</trackback:ping><description><![CDATA[
		<strong>From:</strong> Niels Campbell (<em>niels_campbell_at_lycos.co.uk</em>)<br /><strong>Date:</strong> 01/23/04<br /><pre>Date: 23 Jan 2004 09:14:16 -0800<br />After spending nearly 3 days on this problem to come up with a
<br /></pre><p>
solution I think it is only right to post the solution.
<br /></p><p>I found that you can't set the soTimeout on an HttpURLConnection 
as
<br />
the sockets are encapsulated within the HttpURLConnection
<br />
implementation.
<br /></p><p>I found Mike Reiche solution in which he uses a handler to set a
<br />
timeout value. This nearly worked. Looking at the code in the rt.jar I
<br />
found that the initial timeout was working, but the call
<br />
parseHTTP(...) in HttpClient was then attempting a second connection
<br />
which had a time out value of 0(infinite).
<br /></p><p>I modified the code to override the doConnect() in the 
NetworkClient
<br />
and managed to get a timeout occurring. To be exact two timeouts
<br />
occur.
<br /></p><p>It works on 
<br />
java version "1.4.0_03"
<br />
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_03-b04)
<br />
Java HotSpot(TM) Client VM (build 1.4.0_03-b04, mixed mode)
<br />
and
<br />
java version "1.2.2"
<br />
Classic VM (build JDK-1.2.2_013, native threads, symcjit)
<br /></p><p>Anyway here is the code, excuse the formatting.
<br /></p><p>/* HttpTimeoutURLConnection.java */
<br />
import java.net.*;
<br />
import java.io.*;
<br />
import sun.net.www.http.HttpClient;
<br /></p><p>// Need to override any function in HttpURLConnection that create
 a
<br />
new HttpClient
<br />
// and create a HttpTimeoutClient instead. Those functions are
<br />
// connect(), getNewClient(), getProxiedClient()
<br /></p><p>public class HttpTimeoutURLConnection extends
<br />
sun.net.www.protocol.http.HttpURLConnection
<br />
{
<br /></p><p>    public HttpTimeoutURLConnection(URL u, HttpTimeoutHandler 
handler,
<br />
int iSoTimeout)
<br />
        throws IOException
<br />
    {
<br />
        super(u, handler);
<br />
        HttpTimeoutClient.setSoTimeout(iSoTimeout);
<br />
    }
<br /></p><p>    public void connect() throws IOException
<br />
    {
<br />
        if (connected)
<br />
        {
<br />
            return;
<br />
        }
<br /></p><p>        try
<br />
        {
<br />
            if ("http".equals(url.getProtocol())) // &amp;&amp; 
!failedOnce &lt;-
<br />
PRIVATE
<br />
            {
<br />
                // for safety's sake, as reported by KLGroup
<br />
                synchronized (url)
<br />
                {
<br />
                    http = HttpTimeoutClient.getNew(url);
<br />
                }
<br />
            }
<br />
            else
<br />
            {
<br />
                if (handler instanceof HttpTimeoutHandler)
<br />
                {
<br />
                    http = new HttpTimeoutClient(super.url,
<br />
((HttpTimeoutHandler)handler).getProxy(),
<br />
((HttpTimeoutHandler)handler).getProxyPort());
<br />
                }
<br />
                else
<br />
                {
<br />
                    throw new IOException("HttpTimeoutHandler
<br />
expected");
<br />
                }
<br />
            }
<br /></p><p>            ps = (PrintStream)http.getOutputStream();
<br />
        }
<br />
        catch (IOException e)
<br />
        {
<br />
            throw e;
<br />
        }
<br /></p><p>        connected = true;
<br />
    }
<br /></p><p>    protected HttpClient getNewClient(URL url)
<br />
        throws IOException
<br />
    {
<br />
        HttpTimeoutClient httpTimeoutClient = new HttpTimeoutClient
<br />
(url, (String)null, -1);
<br />
        return httpTimeoutClient;
<br />
    }
<br /></p><p>    protected HttpClient getProxiedClient(URL url, String 
s, int i)
<br />
        throws IOException
<br />
    {
<br />
        HttpTimeoutClient httpTimeoutClient = new HttpTimeoutClient
<br />
(url, s, i);
<br />
        return httpTimeoutClient;
<br />
    }
<br /></p><p>}
<br /></p><p>/* HttpTimeoutHandler.java */
<br />
import java.net.*;
<br />
import java.io.IOException;
<br /></p><p>public class HttpTimeoutHandler extends
<br />
sun.net.www.protocol.http.Handler
<br />
{
<br />
    private int iSoTimeout=0;
<br /></p><p>    public HttpTimeoutHandler(int iSoTimeout)
<br />
    {
<br />
        // Divide the time out by two because two connection attempts
<br />
are made
<br />
        // in HttpClient.parseHTTP()
<br /></p><p>        if (iSoTimeout%2!=0)
<br />
        {
<br />
            iSoTimeout++;
<br />
        }
<br />
        this.iSoTimeout = (iSoTimeout/2);
<br />
    }
<br /></p><p>    protected java.net.URLConnection openConnection(URL u) throws
<br />
IOException
<br />
    {
<br />
        return new HttpTimeoutURLConnection(u, this, iSoTimeout);
<br />
    }
<br /></p><p>    protected String getProxy()
<br />
    {
<br />
        return proxy;
<br />
    }
<br /></p><p>    protected int getProxyPort()
<br />
    {
<br />
        return proxyPort;
<br />
    }
<br />
}
<br /></p><p>/* HttpTimeoutFactory.java */
<br />
import java.net.*;
<br /></p><p>public class HttpTimeoutFactory implements 
URLStreamHandlerFactory
<br />
{
<br />
    private int iSoTimeout=0;
<br /></p><p>    public HttpTimeoutFactory(int iSoTimeout)
<br />
    {
<br />
        this.iSoTimeout = iSoTimeout;
<br />
    }
<br /></p><p>    public URLStreamHandler createURLStreamHandler(String str)
<br />
    {
<br />
        return new HttpTimeoutHandler(iSoTimeout);
<br />
    }
<br />
}
<br /></p><p>/* HttpTimeoutClient.java */
<br />
import sun.net.www.http.HttpClient;
<br />
import java.net.*;
<br />
import sun.net.*;
<br />
import sun.net.www.*;
<br />
import java.io.*;
<br /></p><p>public class HttpTimeoutClient extends HttpClient
<br />
{
<br />
    private static int iSoTimeout=0;
<br /></p><p>    public HttpTimeoutClient(URL url, String proxy, int 
proxyPort)
<br />
throws IOException
<br />
    {
<br />
        super(url, proxy, proxyPort);
<br />
    }
<br /></p><p>    public HttpTimeoutClient(URL url) throws IOException
<br />
    {
<br />
        super(url, null, -1);
<br />
    }
<br /></p><p>    public static HttpTimeoutClient getNew(URL url)
<br />
        throws IOException
<br />
    {
<br />
        HttpTimeoutClient httpTimeoutClient = (HttpTimeoutClient)
<br />
kac.get(url);
<br /></p><p>        if (httpTimeoutClient == null)
<br />
        {
<br />
            httpTimeoutClient = new HttpTimeoutClient (url);  // CTOR
<br />
called openServer()
<br />
        }
<br />
        else
<br />
        {
<br />
            httpTimeoutClient.url = url;
<br />
        }
<br /></p><p>        return httpTimeoutClient;
<br />
    }
<br /></p><p>    public static void setSoTimeout(int iNewSoTimeout)
<br />
    {
<br />
        iSoTimeout=iNewSoTimeout;
<br />
    }
<br /></p><p>    public static int getSoTimeout()
<br />
    {
<br />
        return iSoTimeout;
<br />
    }
<br /></p><p>    // Override doConnect in NetworkClient
<br /></p><p>    protected Socket doConnect(String s, int i)
<br />
        throws IOException, UnknownHostException, SocketException
<br />
    {
<br />
        Socket socket=super.doConnect(s,i);
<br /></p><p>        // This is the important bit
<br />
        socket.setSoTimeout(iSoTimeout);
<br />
        return socket;
<br />
    }
<br /></p><p>}
<br /></p><p>/* Example use */
<br />
import java.util.*;
<br />
import java.io.*;
<br />
import java.net.*;
<br /></p><p>public class SystemProperty
<br />
{
<br />
    public static void main(String[] args)
<br />
    {
<br />
        String sSoapUrl="<a href="http://192.168.0.223/mobaqSecurity/SslTunnelServlet">http://192.168.0.223/mobaqSecurity/SslTunnelServlet</a>";
<br />
        System.out.println("Connecting to [" + sSoapUrl + "]");
<br /></p><p>        URLConnection urlConnection = null;
<br />
        URL url=null;
<br /></p><p>        try
<br />
        {
<br />
            url = new URL((URL)null, sSoapUrl, new
<br />
HttpTimeoutHandler(10000));
<br />
            urlConnection = url.openConnection();
<br /></p><p>            // Optional
<br />
            url.setURLStreamHandlerFactory(new
<br />
HttpTimeoutFactory(10000));
<br /></p><p>            System.out.println("Url class
<br />
["+urlConnection.getClass().getName()+"]");
<br />
        }
<br />
        catch (MalformedURLException mue)
<br />
        {
<br />
            System.out.println("&gt;&gt;MalformedURLException&lt;&lt;");
<br />
            mue.printStackTrace();
<br />
        }
<br />
        catch (IOException ioe)
<br />
        {
<br />
            System.out.println("&gt;&gt;IOException&lt;&lt;");
<br />
            ioe.printStackTrace();
<br />
        }
<br /></p><p>        HttpURLConnection httpConnection =
<br />
(HttpURLConnection)urlConnection;
<br />
        System.out.println("Connected to [" + sSoapUrl + "]");
<br /></p><p>        byte[] messageBytes=new byte[10000];
<br />
        for (int i=0; i&lt;10000; i++)
<br />
        {
<br />
            messageBytes[i]=80;
<br />
        }
<br /></p><p>        try
<br />
        {
<br />
            httpConnection.setRequestProperty("Connection", "Close");
<br />
            httpConnection.setRequestProperty("Content-Length",
<br />
String.valueOf(messageBytes.length));
<br />
            httpConnection.setRequestProperty("Content-Type",
<br />
"text/xml; charset=utf-8");
<br />
            httpConnection.setRequestMethod("POST");
<br />
            httpConnection.setDoOutput(true);
<br />
            httpConnection.setDoInput(true);
<br />
        }
<br />
        catch (ProtocolException pe)
<br />
        {
<br />
            System.out.println("&gt;&gt;ProtocolException&lt;&lt;");
<br />
            pe.printStackTrace();
<br />
        }
<br /></p><p>        OutputStream outputStream=null;
<br /></p><p>        try
<br />
        {
<br />
            System.out.println("Getting output stream");
<br />
            outputStream =httpConnection.getOutputStream();
<br />
            System.out.println("Got output stream");
<br /></p><p>            outputStream.write(messageBytes);
<br />
        }
<br />
        catch (IOException ioe)
<br />
        {
<br />
            System.out.println("&gt;&gt;IOException&lt;&lt;");
<br />
            ioe.printStackTrace();
<br />
        }
<br /></p><p style="">        try
<br />
        {
<br />
            System.out.println("Getting input stream");
<br />
            InputStream is=httpConnection.getInputStream();
<br />
            System.out.println("Got input stream");
<br /></p><p>            byte[] buf = new byte[1000];
<br />
            int i;
<br /></p><p>            while((i = is.read(buf)) &gt; 0)
<br />
            {
<br />
                System.out.println(""+new String(buf));
<br />
            }
<br />
            is.close();
<br />
        }
<br />
        catch (Exception ie)
<br />
        {
<br />
            ie.printStackTrace();
<br />
        }
<br /></p><p>    }
<br />
}
<br /></p>Cheers,
<br />
Niels
<br /><br />来源:http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2004-01/3271.html<br />     http://www.weblogicfans.net/viewthread.php?tid=1101<br />     http://forums.sun.com/thread.jspa?threadID=568948<br />备注：在HttpTimeoutClient类中的第二个构造函数中的：super(url,null,-1)改为super(url,
(String)null,-1)即可。<br /><img src ="http://www.blogjava.net/leekiang/aggbug/318274.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2010-04-14 17:04 <a href="http://www.blogjava.net/leekiang/archive/2010/04/14/318274.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HttpURLConnection设置网络超时</title><link>http://www.blogjava.net/leekiang/archive/2010/04/13/318185.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Tue, 13 Apr 2010 11:00:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2010/04/13/318185.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/318185.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2010/04/13/318185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/318185.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/318185.html</trackback:ping><description><![CDATA[Java中可以使用HttpURLConnection来请求WEB资源。<br />HttpURLConnection对象不能直接构造，需要通过
URL.openConnection()来获得HttpURLConnection对象，示例代码如下：<br />String urlStr= <a href="http://www.jaddy.org/">www.ttt.org</a>;<br />URL url = new 
URL(urlStr);<br />HttpURLConnection conn = 
(HttpURLConnection)url.openConnection();
<p> </p><p style="line-height: 150%;">HttpURLConnection是基于HTTP协议的，其底层通过socket通信实
现。如果不设置超时（timeout），在网络异常的情况下，可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时：<br />System.setProperty("sun.net.client.defaultConnectTimeout",
 超时毫秒数字符串);<br />System.setProperty("sun.net.client.defaultReadTimeout", 
超时毫秒数字符串);<br /></p><p style="line-height: 150%;">其中： 
sun.net.client.defaultConnectTimeout：连接主机的超时时间（单位：毫秒）<br />sun.net.client.defaultReadTimeout：
从主机读取数据的超时时间（单位：毫秒） </p><p style="line-height: 150%;">例如：<br />System.setProperty("sun.net.client.defaultConnectTimeout",
 "30000");<br />System.setProperty("sun.net.client.defaultReadTimeout", 
"30000"); </p><p style="line-height: 150%;">JDK 
1.5以前的版本，只能通过设置这两个系统属性来控制网络超时。在1.5中，还可以使用HttpURLConnection的父类
URLConnection的以下两个方法：<br />setConnectTimeout：设置连接主机超时（单位：毫秒）<br />setReadTimeout：
设置从主机读取数据超时（单位：毫秒） </p><p style="line-height: 150%;">例如：<br />HttpURLConnection urlCon = 
(HttpURLConnection)url.openConnection();<br />urlCon.setConnectTimeout(30000);<br />urlCon.setReadTimeout(30000); <br /></p><p style="line-height: 150%;">来源:http://www.xd-tech.com.cn/blog/article.asp?id=37</p><p style="line-height: 150%;">另外可参考<a target="_blank" href="http://hi.baidu.com/xisct/blog/item/e0ba1fa7a49ee291d0435834.html">java中处理http连接超时的方法</a></p><p style="line-height: 150%;"><a target="_blank" href="/supercrsky/articles/247449.html">JDK中的URLConnection参数详解<br /></a></p><p style="line-height: 150%;"><a target="_blank" href="http://hi.baidu.com/%CE%DE%D0%C4%CF%F2%BA%F3/blog/item/3e00d5805869a0a90df4d245.html">linux下设置connect连接超时的方法</a></p><p style="line-height: 150%;"><a href="http://lgh3292.javaeye.com/blog/283425" style="" target="_blank">java socket 用法(一)<br /></a></p><p style="line-height: 150%;">Linux，可以修改/proc/sys/net/ipv4/tcp_syn_retries的值，缺省是72，大约5分钟左右，改小点时间就短些</p><img src ="http://www.blogjava.net/leekiang/aggbug/318185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2010-04-13 19:00 <a href="http://www.blogjava.net/leekiang/archive/2010/04/13/318185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网络协议笔记</title><link>http://www.blogjava.net/leekiang/archive/2009/03/22/261336.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Sun, 22 Mar 2009 10:31:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2009/03/22/261336.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/261336.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2009/03/22/261336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/261336.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/261336.html</trackback:ping><description><![CDATA[OSI是一个开放性的通行系统互连参考模型，他是一个定义的非常好的协议规范。OSI模型有7层结构，每层都可以有几个子层。<br />OSI七层模型是一个很好的理论模型，但是在实际应用中都做了裁剪。尤其是TCP/IP的盛行，把7层结构压成了4层，<br />所以很多人都批评OSI七层模型过于复杂，但是作为一个完整的全面的网络模型，还是被大家非常认可的。OSI的7层从上到下分别是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。<br />7层的功能描述： <br />（1）
应用层：与其他计算机进行通讯的一个应用，它是对应应用程序的通信服务的。例如，一个没有通信功能的字处理程序就不能执行通信的代码，从事字处理工作的程
序员也不关心OSI的第7层。但是，如果添加了一个传输文件的选项，那么字处理器的程序员就需要实现OSI的第7层。示
例：telnet，HTTP,FTP,WWW,NFS,SMTP等。 <br />（2）表示层：这一层的主要功能是定义数据格式及加密。例如，FTP允许
你选择以二进制或ASII格式传输。如果选择二进制，那么发送方和接收方不改变文件的内容。如果选择ASII格式，发送方将把文本从发送方的字符集转换成
标准的ASII后发送数据。在接收方将标准的ASII转换成接收方计算机的字符集。示例：加密，ASII等。 <br />（3）会话层：他定义了如何开始、控制和结束一个会话，包括对多个双向小时的控制和管理，以便在只完成连续消息的一部分时可以通知应用，从而使表示层看到的数据是连续的，在某些情况下，如果表示层收到了所有的数据，则用数据代表表示层。示例：RPC，SQL等。 <br />（4）传输层：这层的功能包括是否选择差错恢复协议还是无差错恢复协议，及在同一主机上对不同应用的数据流的输入进行复用，还包括对收到的顺序不对的数据包的重新排序功能。示例：TCP，UDP，SPX。 <br />（5）网络层：这层对端到端的包传输进行定义，他定义了能够标识所有结点的逻辑地址，还定义了路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质，网络层还定义了如何将一个包分解成更小的包的分段方法。示例：IP,IPX等。 <br />（6）数据链路层：他定义了在单个链路上如何传输数据。这些协议与被讨论的歌种介质有关。示例：ATM，FDDI等。 <br />（7）物理层：OSI的物理层规范是有关传输介质的特性标准，这些规范通常也参考了其他组织制定的标准。连接头、针、针的使用、电流、电流、编码及光调制等都属于各种物理层规范中的内容。物理层常用多个规范完成对所有细节的定义。示例：Rj45，802.3等。<br />来源:http://blog.csdn.net/wanghao72214/archive/2009/03/18/4000806.aspx<br /><img src ="http://www.blogjava.net/leekiang/aggbug/261336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2009-03-22 18:31 <a href="http://www.blogjava.net/leekiang/archive/2009/03/22/261336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java io笔记</title><link>http://www.blogjava.net/leekiang/archive/2009/03/17/260275.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Tue, 17 Mar 2009 08:32:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2009/03/17/260275.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/260275.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2009/03/17/260275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/260275.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/260275.html</trackback:ping><description><![CDATA[
		<strong>File.separatorChar</strong> 返回一个字符，表示当前系统默认的文件名分隔符，<strong><font color="#cc0000">在Windows中为"\",unix中为"/"</font></strong>。<br /><strong>File.separator</strong> 与前者相同，但将分隔符作为字符串类型返回。<br /><strong>pathSeparatorChar</strong> 返回一个字符，表示当前系统默认的路径名分隔符，<strong><font color="#cc0000">在Windows中为";",unix中为":"</font></strong>。<br /><strong>File.pathSeparator</strong> 与前者相同，但将分隔符作为字符串类型返回。<img src ="http://www.blogjava.net/leekiang/aggbug/260275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2009-03-17 16:32 <a href="http://www.blogjava.net/leekiang/archive/2009/03/17/260275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>