Apache HttpClient 4.0 failing to timeout for socket on Android - java

I'm working on an Android application that requires the use of HttpClient in order to upload a file from the Android device to a web server. The file I'm uploading can reach sizes up to 1 Gb, and so timeouts can occur if the device loses connection during the upload. The weird thing is that the timeout I set for the socket doesn't seem to have any effect. The application would just hang whenever I lose connection instead of raising the SocketTimeoutException.
I tried using:
HttpConnectionParams.setConnectionTimeout(params, CrashLogParams.TIMEOUT);
HttpConnectionParams.setSoTimeout(params, CrashLogParams.TIMEOUT);
but this only worked for the connection timeout, not the socket timeout. Also I tried:
HttpParams p = httpclient.getParams();
p.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
p.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
The reason I know that connection timeout works is because, I would get the exception for connection timeout after executing
httpclient.execute(httppost);
The application seems to hang when connection is lost during upload, but after the application has successfully made a connection to the server.
To test my app, I disabled the network at different times to see how the application would react. If I disable the network before sending the request, I get a connection error and my application can gracefully handle that, but if I disable it during upload the application hangs. Of course I'm doing all these requests through AsyncTasks, so the main UI Thread doesn't crash. I'm just wondering if there is any other way to make sure that the socket will timeout upon not receiving any data, or if I'm missing anything here. I've read many blogs and posts, but most of them just suggest using SO_TIMEOUT which doesn't work for me.
sotimeout not working in a multipart http post on android 2.1

Are you creating your own ClientConnectionManager? Take a look at the source for AndroidHttpClient.newInstance().
They create a new BasicHttpParams object and pass it to the constructors for both a ThreadSafeClientConnectionManager and the DefaultHttpClient. I don't see a way to set parameters on the ClientConnectionManager except in the constructor.

I'm facing the same problem as you, with the same use case. It happens on a samsung galaxy s2 running android 2.3.6 but not with the same device on 4.x . Unfortunately this is exactly the device my customer uses, and it runs fine on roughly 10 other test devices with various Android versions and constructors...
I spent hours trying with HttpUrlConnection library instead of HttpClient from Apache, but the end result is the same. AndroidHttpClient shows the same behavior. This leads me to say that it sounds like an hardware implementation or OS related problem...
The only workaround I found was to put the HttpClient.execute() method in a separate thread and call thread.join(timeout) as a security to stop the thread if anything goes wrong. The drawback is when upload runs fine but takes longer than the timeout, the request is interrupted...
If you found something in the meantime, I would greatly appreciate if you could share it.

Related

SocketTimedOut when connecting to https Url through CXF

I am facing a problem with CXF framework trying to connect to a https backend service. Since the service is out side of my network I am using a proxy to connect. I am getting a SocketTimedOutException when I set the readTimeout Value to like 60000 which is the default. When I set the timeout to 0(infinite) it gives a connectionResetException after a while. I wrote a program on my own which used HttpsUrlConnection to connect to the same service with proxy and I am able to work with it.
I was initially under the feeling that the connection itself was not happening but later I came to know that that would have thrown a ConnectException rather than a socketException. It gave me some relief , but I want to know how I can deal with the SocketException, both the timeout and the Connection Reset.
Please explain to me whoever knows about this.
Thanks,
Sachin
You should blame on your network or your proxy, but not your codes. SocketTimedOutException and ConnectionTimedOutException are thrown when network is blocked or weak. So, the solution to both exceptions is smoothening your network.

Force Embedded Jetty to disconnect at once

I'm creating a small utility which receives a lot of HTTP requests. It is written in java and uses embedded-jetty to handle requests via https.
I have a load-testing tool for it, but when it is being run for some time it starts to throw exceptions:
java.net.BindException: Address already in use: connect
(note, this is on sender's side, not in my project)
As I understand this means no more free sockets were found in system when another connect was called. Throughput is about 1000 requests per second, and failures start to appear somewhere after 20000 to 50000 requests.
However when I use the same load testing tool with another program (a kind of simple consumer, written in scala using netty by some colleague - it simply receives all requests and returns empty ok response) - there is no so problem with sockets (though typical speed is 1.5-2 times slower).
I wonder if this could be fixed by telling Jetty somehow to close connections immediately after response was sent. Anyway each new request is sent via new connection. I tried to play with Connector#setIdleTimeout - it seems to be 30000 by default but have not succeeded.
What can I do to fix this - or at least to research the matter deeper to find its cause (if I am wrong in my suggestions)?
UPD Thanks for suggestions, I think I am not allowed to post the source, but I get the idea that I should study client's code (this will make me busy for some time since it is written in scala).
I found that really there was a problem with client - it sends requests with Connection: Keep-Alive in header, though creates new HttpURLConnection for each request and calls disconnect() method after it.
To solve this trouble on the server-side it was sufficient to send Connection: close in response header, since I have no allowance to change testing utility.

Java on Android - Strange socket behavior with InputStream timeout errors

I have an app which uses an instance of the Socket class to communicate with a server.
I use the streams returned by socket.getInputStream() and socket.getOutputStream() to read and write data.
When my Android app is always "active" (not minimized), there is no problem with the communication. It does not matter how long the connection lasts.
When I "pause" the application and re-open it quickly, everything still works fine.
However, when I pause the application for about 5 minutes and re-open it, the InputStream shows strange behavior: it stops reading anything. I get timeout errors instead of the data sent by the server.
The connection is still alive, the server is able to write and read. isInputShutdown() on the client-side returns false.
Using a network analysis tool, I can also see that the data sent by the server IN FACT reaches the client but it somehow does not get recognized by the InputStream ...
However, writing data from the client to the server using the OutputStream works fine.
Maybe it's worth mentioning that the socket object and the streams are declared as static to be accessible for all the activities of the app. But as I don't have any problems with the OutputStream, I cannot imagine that this could be the reason.
The only workaround I have at this point is to close the whole socket and connect a new one to the server. But this is causing unnecessary network traffic because I have to handshake again. It would be better not to do it this way.
If anyone has had similar experience and found a solution, I would be really happy if you could share it with me.
You should create a service that will be run in background and implement socket connection with a server.
As Kevin Krumwiede pointed out by referring to this post: Strange behavior of socket outputstream android, when sending data every X minutes (e.g. 3 or 4), everything still works as it should even after 30 minutes of being 'paused'.
I had the hope that Socket.setKeepAlive(true) would be enough to keep the connection alive so I dont have to cause too much unnecessary network traffic but in my particular case, this does not help.
Sending 1 byte of 'garbage' every X minutes 'solves' the problem.

Setting setChunkedStreamingMode in HttpURLConnection fails to deliver data to server

My server version is as follows on my dev machine:
Apache/2.2.21 (Win32) mod_fcgid/2.3.6
I have been testing HttpURLConnection as my project requires easy streaming capabilties. I have read a great synopsis from #BalusC on how to use the class.
Using java.net.URLConnection to fire and handle HTTP requests
The trouble I am currently having is when setting setChunkedStreamingMode. Regardless of what I set it to my stream doesn't seem to make it to the server the data stream is empty when my server api method/connection is called/made. However, if I remove it, it works fine.
I have seen another person with a similar issue:
Java/Android HttpURLConnection setChunkedStreamingMode not working with all PHP servers
But with no real resolution. I am unable to set it to setFixedLengthStreamingMode simply because the content (json) is variable in length.
This is NOT OK. I potentially will be transfering very large quantities of data and hence cannot have the data stored in memory.
My question is, how can I get setChunkedStreamingMode to play nice? Is it a server setup issue or can it be fixed in code?
EDIT
I have now tested my code on my production server and it works no problem. I would however still like to know why my Apache server on my local machine fails. Any help is still much appreciated.
Try adding this HTTP header:
urlConnection.setRequestHeader("Transfer-Encoding","chunked");
I haved a problem like this: although I haved set the chunked HTTP streaming mode (urlConnection.setChunkedStreamingMode(0) ), it not worked, but putting the HTTP header above it works fine.
I had a similar issue. In my case it was the client system that had a virus scanner installed. Those scanners sometimes have identity theft modules that intercept POSTs, scan the body and then pass it on.
In my case BitDefender cached about 5MB before passing it on.
If the whole payload was less then the POST was delivered as non chunked fixed length request.
I had a similar problem using HttpURLConnection. Just add:
conn.setRequestProperty("connection", "close"); // disables Keep Alive
to your connection or disable it for all connections:
System.setProperty("http.keepAlive", "false");
From the API about disconnect():
Releases this connection so that its resources may be either reused or closed.
Unlike other Java implementations, this will not necessarily close socket connections that can be reused. You can disable all connection reuse by setting the http.keepAlive system property to false before issuing any HTTP requests.

HTTP client-server, I don't think i'm closing my client side connections with BasicResponseHandler()

I have a server implemented using Apache HTTPCore which can accept posts from an httpclient implementation. I have enough of it working so that I can send to the server, processes the post contents, and get the response back on the client. Everything seems to work, however I am noticing that the server keeps the connection alive until it times out, even though the client connection has completed successfully. I'm assuming that I need to close the connection on the client side after receiving the response, however I believe I am already doing that as I am using BasicResponseHandler(), which returns a String, so I can't figure out what if anything I need to actually close.
Any thoughts on this? I was going to try using a different response handler that returns an InputStream, and see if closing that works, but I assumed that BasicResponseHandlerwas doing that behind the scenes already as it returns a String
If the server hasn't read an EOS, the client hasn't closed the connection. Having a read timeout on the connection to the client is the correct strategy.

Categories