msbroadf
asked on
URLConnection blocked
I have two URLConnections opened at the same time in my java applet. One waits up to 1 minute for a webpage to return, while the other gets a web page and returns almost instantly. I find that after the applet has made several requests for a web page it deadlocks. The deadlock appears to be caused by the long waiting URLConnection blocking in the getInputStream function which stops the other quick URL connections from being created. Does anyone know how a url connection is implemented lower down. Is a deadlock occuring? Is URLConnection sharing one socket or stream or something?
Put every connection in a separate thread which will not block the main thread, and synchronize them if you need to. Can you post sample code from your applet ?
ASKER
public class Engine extends Thread
{
private volatile boolean shutdown;
...
...
public void run()
{
while (!shutdown)
{
String line = getTunnelLine()
if (!shutdown) processLine(line);
}
/**
* Opens the connection to the proxy
*/
private URLConnection openTunnel(String file)
{
URLConnection result;
try
{
URL url = new URL("http" + (applet.secure ? "s" : "") + "://" + tunnelHost + ":" + (applet.secure ? "443" : new Integer(tunnelPort).toStri ng().trim( )) + file);
result = url.openConnection();
}
catch (Exception e)
{
System.err.println("openTu nnel:" + e);
result = null;
}
return result;
}
/**
* Gets a line of data from the HTTP tunnel
* This function gets the long HTML page
* and blocks all other openTunnel request
* from executing. It is called from the engine
* run().
*/
private String getTunnelLine()
{
String result = "";
if (getLineBuffer.size() > 0)
{
result = (String) getLineBuffer.firstElement ();
getLineBuffer.removeElemen tAt(0);
}
else
{
URLConnection conn = openTunnel("/csd/proxy.cgi ?cssesstok en=" + cssesstoken + "&unum=" + uniqueNum++ + "&csconnectionstyle=sendan dclose");
if (conn != null)
{
conn.setAllowUserInteracti on(true);
conn.setUseCaches(false);
conn.setDoInput(true);
if (connectTunnel(conn))
{
applet.message(applet.getR esourceStr ing("r50") );
BufferedReader br = getBufferedReader(conn);
if (br != null)
{
String lines = readBufferedReader(br);
if (lines != null)
{
last_io = new Date();
result = parseLines(lines);
if (debugIn) System.err.println("In =" + result);
}
else
error = true;
closeBufferedReader(br);
}
else
error = true;
}
else
error = true;
closeTunnel(conn);
}
else
error = true;
}
return result;
}
/**
* The tunnel outline calls the quick
* html page.
* Tunnel the data sent to the server
* so it looks like an HTTP POST request. This
* function is called when the user clicks buttons
* on the applet to send data back to the server
* however. It cant get bufferedreader after a while
* because getTunnelLine is also blocking on get
* buffered reader
*/
public void tunnelOutline(String data)
{
PrintWriter out = null;
BufferedReader in = null;
boolean success;
String postData = "cssesstoken=" + cssesstoken + "&" + "cschatinput=" + encode(data) + "&" + "csconnectionstyle=sendonl y\r\n";
if (useProxy)
{
URLConnection conn = openTunnel("/CSJava/CSCPRO XY.CGI?css esstoken=" + cssesstoken + "&cschatinput=" + encode(data) + "&csconnectionstyle=sendon ly");
if (conn != null)
{
conn.setUseCaches(false);
conn.setDoInput(true);
if (connectTunnel(conn))
in = getBufferedReader(conn);
else
error = true;
closeTunnel(conn);
}
else
error = true;
}
else
{
Socket s = getSocket(tunnelHost, tunnelPort);
if (s != null)
{
out = getPrintWriter(s, true);
in = getBufferedReader(s);
out.print("POST /CSJava/CSCPROXY.CGI HTTP/1.1\r\n" +
"Host: " + tunnelHost + ":" + tunnelPort + "\r\n" +
"Content-type: application/x-www-form-url encoded\r\ n" +
"Content-length: " + postData.length() + "\r\n\r\n");
out.print(postData);
out.flush();
}
}
if (in != null)
{
try
{
StringBuffer buf = new StringBuffer();
int input;
while ((input = in.read()) > -1)
buf.append((char)input);
if (!useProxy) out.close();
in.close();
}
catch (Exception e)
{
error = true;
}
}
if (error && debugOut) System.err.println(data + " may not have been sent");
}
private BufferedReader getBufferedReader(URLConne ction conn)
{
BufferedReader result;
try
{
result = new BufferedReader(new InputStreamReader(conn.get InputStrea m()));
}
catch (Exception e)
{
System.err.println("getBuf feredReade r error: " + e.getMessage());
result = null;
}
return result;
}
}
{
private volatile boolean shutdown;
...
...
public void run()
{
while (!shutdown)
{
String line = getTunnelLine()
if (!shutdown) processLine(line);
}
/**
* Opens the connection to the proxy
*/
private URLConnection openTunnel(String file)
{
URLConnection result;
try
{
URL url = new URL("http" + (applet.secure ? "s" : "") + "://" + tunnelHost + ":" + (applet.secure ? "443" : new Integer(tunnelPort).toStri
result = url.openConnection();
}
catch (Exception e)
{
System.err.println("openTu
result = null;
}
return result;
}
/**
* Gets a line of data from the HTTP tunnel
* This function gets the long HTML page
* and blocks all other openTunnel request
* from executing. It is called from the engine
* run().
*/
private String getTunnelLine()
{
String result = "";
if (getLineBuffer.size() > 0)
{
result = (String) getLineBuffer.firstElement
getLineBuffer.removeElemen
}
else
{
URLConnection conn = openTunnel("/csd/proxy.cgi
if (conn != null)
{
conn.setAllowUserInteracti
conn.setUseCaches(false);
conn.setDoInput(true);
if (connectTunnel(conn))
{
applet.message(applet.getR
BufferedReader br = getBufferedReader(conn);
if (br != null)
{
String lines = readBufferedReader(br);
if (lines != null)
{
last_io = new Date();
result = parseLines(lines);
if (debugIn) System.err.println("In =" + result);
}
else
error = true;
closeBufferedReader(br);
}
else
error = true;
}
else
error = true;
closeTunnel(conn);
}
else
error = true;
}
return result;
}
/**
* The tunnel outline calls the quick
* html page.
* Tunnel the data sent to the server
* so it looks like an HTTP POST request. This
* function is called when the user clicks buttons
* on the applet to send data back to the server
* however. It cant get bufferedreader after a while
* because getTunnelLine is also blocking on get
* buffered reader
*/
public void tunnelOutline(String data)
{
PrintWriter out = null;
BufferedReader in = null;
boolean success;
String postData = "cssesstoken=" + cssesstoken + "&" + "cschatinput=" + encode(data) + "&" + "csconnectionstyle=sendonl
if (useProxy)
{
URLConnection conn = openTunnel("/CSJava/CSCPRO
if (conn != null)
{
conn.setUseCaches(false);
conn.setDoInput(true);
if (connectTunnel(conn))
in = getBufferedReader(conn);
else
error = true;
closeTunnel(conn);
}
else
error = true;
}
else
{
Socket s = getSocket(tunnelHost, tunnelPort);
if (s != null)
{
out = getPrintWriter(s, true);
in = getBufferedReader(s);
out.print("POST /CSJava/CSCPROXY.CGI HTTP/1.1\r\n" +
"Host: " + tunnelHost + ":" + tunnelPort + "\r\n" +
"Content-type: application/x-www-form-url
"Content-length: " + postData.length() + "\r\n\r\n");
out.print(postData);
out.flush();
}
}
if (in != null)
{
try
{
StringBuffer buf = new StringBuffer();
int input;
while ((input = in.read()) > -1)
buf.append((char)input);
if (!useProxy) out.close();
in.close();
}
catch (Exception e)
{
error = true;
}
}
if (error && debugOut) System.err.println(data + " may not have been sent");
}
private BufferedReader getBufferedReader(URLConne
{
BufferedReader result;
try
{
result = new BufferedReader(new InputStreamReader(conn.get
}
catch (Exception e)
{
System.err.println("getBuf
result = null;
}
return result;
}
}
Can't see any obvious problem in your code.
Have you checked what your server is recieving and whether it is blocking?
Have you checked what your server is recieving and whether it is blocking?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
- points to heyhey_
Please leave any comments here within the
next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !
girionis
Cleanup Volunteer
I will leave a recommendation in the Cleanup topic area that this question is:
- points to heyhey_
Please leave any comments here within the
next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !
girionis
Cleanup Volunteer
Can you post the relevant part of your code so we can see whats going on.