Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - random "Cannot connect to host" with 3G

I am working on an iOS application which works as a thin client for a bussiness server. There is a lot of requests sent to the server, a lot of data downloaded.

I don't use any fancy request frameworks, just asynchronous NSURLConnection with a delegate.

The application usually works very well with both wifi and 3G BUT

some users report random disconnects when using 3G (in USA). All request are okey but once in a while a request fails with "Cannot Connect to Host" (-1004) error.

This affects user experience a lot.

Some facts:

  1. It doesn't happen on wifi
  2. Users report that it doesn't happen with other applications when using 3G.
  3. It's not a timeout issue, the error appears 0.3-1.0 secs after starting the connection.
  4. We were not able to reproduce the problem using traceroute.
  5. Using SCNetworkReachability the host appears to be reachable (I know the limitations of this API).

Question What could be the cause of the problem? What connection properties can differ with 3G and wifi? How can I debug it?

Currently the only solution I see is to try to send the request again if the previous request has failed. However, I would like to find the cause of the problem first.

EDIT The problem was probably caused by one of our routers. IT guys are still inspecting the problem.

like image 545
Sulthan Avatar asked Jul 31 '12 20:07

Sulthan


1 Answers

All error codes can be found in the Apple documentation under the section

CFNetwork Error Codes Reference

The code -1004 is described only as

kCFURLErrorCannotConnectToHost

The connection failed because a connection cannot be made to the host. Available in OS X v10.6 and later. Declared in CFNetworkErrors.h.

It basically means that the user has a connection (he is not on flightmode, data traffic is turned on, and his phone is registered in the network, you had a valid URL etc) but was actively prevented from connecting to the server. If the server was not responding, you would have had something more like a time out error after a longer waiting time, as you described. This kind of error is probably caused by something preventing the traffic to the server and can for example happen if the user is behind a firewall or a proxy.

The issue could actually be caused by the provider, especially if you have no issues with some users, and random issues with others.

As some other poster said, you could try to ask your users about their service provider, and more details about their location, or what they were doing when they got the error (like sitting in a vehicle or having bad reception in the countryside)

If you can't find any patterns, and if the error really just occur randomly and only for some users, and just sometimes, I would just consider it to be another unevitable issue that can be caused by the fact that mobile phones are never guaranteed to be connected all the time, and that some cellphone providers may not always deliver 100% of all packages that should be delivered out there... what you need to do then is just to handle the error.

Build away the error by simply retrying, and not showing it to the user, at least not until after a sufficient amount of retries.

One last thing to consider:

If you send lots and lots of requests from your app, and lots of data, make sure that you are not "overconsuming" by spamming huge amounts of unfinished requests. This could cause the server or some proxy server on the way to refuse your request because it is too busy answering your other request. A refused request could cause an error like that. Make sure to send a reasonable amount of requests so that your user's device has time to "breathe".

Let your retry-scheme be a smart one where you start out by retrying a bunch of times within shorter time, and if it keeps failing, increase the time span to the next retry.

like image 84
jake_hetfield Avatar answered Sep 17 '22 15:09

jake_hetfield