1

I'm trying to post a video file to our server and monitor it's progress. I followed the steps outlined in Can't grab progress on http POST file upload (Android) and that worked great, but with larger files my program will hang while writing to the output socket and subsequently cause my phone to lock the WiFi so I can't turn it on/off and then cause it to crash (after a short period).

So I attempted to write my own HTTPClient and it works, but also with intermittent success, still falling victim to the random crashes of the method outlined above. It seems this only occurs on files > 5MB, but I've had it die around 1.3MB and I've even had it successfully transfer a 13MB file. The fact that it's so random and sporadic is infuriating but I'm convinced there's some reason it's happening.

Here's my connection code:

socket.connect(new InetSocketAddress(host, port));
socket.setSendBufferSize(1024 * 65);

int bytesSent = 0;
PrintStream out = new PrintStream(socket.getOutputStream());
out.print(headersBuffer);
out.print(bodyBuffer);
bytesSent += headersBuffer.length() + headersBuffer.length();
byte[] bytes = new byte[1024 * 65];
int size;
while ((size = fileStream.read(bytes)) > 0) {
    mListener.transferred(bytesSent);
    Log.i(TAG, "bytes sent: " + bytesSent);
    bytesSent += size;
    out.write(bytes, 0, size);       // Random freezes (/blocking?) on this line
    out.flush();
}

Log.i(TAG, "Made it!");
out.print(lastBoundary);
out.flush();

I've used the debugger to see where it's getting to in the stack when the write just seems to block and it's the OSNetworkSystem.writeSocketImpl() function. That function just never returns...

So my next thought was - if the socket will just sit there, perhaps I can interrupt it and force it to close so at least the phone doesn't crash and the user can retry... I read up on force closing sockets in Android here (since it seems there are some problems): http://code.google.com/p/android/issues/detail?can=2&q=7933&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&id=7933

Basically what I did was create a Listener thread that looks at how many bytes have been transferred every 500ms and if there hasn't been a change, attempt to force close the socket by means of

socket.shutdownOutput();
socket.close();

However the socket returns that it is closed and everything proceeds to fail as outlined above.

Here's the general sequence of events in Logcat:

12-21 14:25:26.802  2234  2340 V UploadService: Bytes transferred: 5959800 of: 13191823
12-21 14:25:26.802  2234  2340 V UploadService: Bytes transferred: 5963896 of: 13191823
12-21 14:25:26.802  2234  2340 V UploadService: Bytes transferred: 5967992 of: 13191823
12-21 14:26:00.693  1262  1270 D WifiService: acquireWifiLockLocked: WifiLock{NetworkLocationProvider type=2 binder=android.os.Binder@45b48958}
12-21 14:26:11.083  1262  1289 D WifiHW  : 'DRIVER LINKSPEED' command timed out.
12-21 14:26:21.130  1262  1500 D WifiHW  : 'AP_SCAN 2' command timed out.
12-21 14:26:31.177  1262  1500 D WifiHW  : 'SCAN' command timed out.

And after a few minutes the really bad stuff starts happening and the phone crashes!

Please help! Thank you.

EDIT: Works great over 3G - I'm going to try at home and see if its some sort of router issue. However - how can I catch this problem and prevent the phone from crashing?

Community
  • 1
  • 1
Mark G.
  • 3,176
  • 1
  • 27
  • 29
  • Are you sure that the server is pulling all of the data out of the socket as it's sent to it? If it stops reading from the socket for some reason, that would cause the kind of blocking that you're describing. (It shouldn't cause a crash or a hang, though.) – Dan Breslau Dec 22 '10 at 00:57
  • Uploading a video to youtube makes the same thing happen so it's gotta be something on my side - but the youtube app is able to catch the error before anything bad happens and forces the phone to shutdown. I'm almost convinced this has to do with the WifiHW errors in Logcat shown above. – Mark G. Dec 22 '10 at 01:16
  • By the way, it might be worth checking the output from a call to `socket.getSendBufferSize()` after you've called `socket.setSendBufferSize()`, because the latter only provides a hint to the system -- there's no guarantee that that's the size that you'll get. (Not that it should really matter.) – Dan Breslau Dec 22 '10 at 01:25
  • @Mark37: I'm confused about what you mean by "youtube makes the same thing happen...but the youtube app is able to catch the error before anything bad happens". Which stuff do you see youtube doing, and which things does it not do? – Dan Breslau Dec 22 '10 at 01:41
  • Some things I'd try, with no particular guarantee of success: 1) Using a somewhat smaller buffer size (32k?). 2) Add a small delay between writes, just for testing purposes (maybe 1/10 sec?). 3) If you have enabled using wifi for location, then disable it. – Dan Breslau Dec 22 '10 at 01:43
  • @Dan Breslau - Sorry for not being more clear - The youtube app when uploading a file will also error out on upload and cause the Wifi adapter to throw the same "WifiHW : 'DRIVER LINKSPEED' command timed out." error on Logcat. The difference is that youtube is able to catch the error and stop the upload whereas my app will just hang. I'm going to check the server and see if its pulling the information from the socket and try some of your suggestions. – Mark G. Dec 22 '10 at 05:18
  • 1
    Ok so I just confirmed that it is indeed the Wifi connection at my office causing the problems - the upload works fine from my home network... but I still need to figure out how to catch the error that's happening up above. – Mark G. Dec 22 '10 at 08:37
  • Any ideas how I could possibly check whether its reading all the data from the server side? I've got apache/php running on my server. – Mark G. Dec 22 '10 at 19:44
  • @Mark37: In the best case, you have a file on disk whose size is equal to the number of bytes that your Android sent. If there's no file, or if the file size is smaller than the number of bytes you sent, check the log files. If there are no log files, see if an Apache administrator can configure appropriate logging. (I can't help you there.) – Dan Breslau Dec 22 '10 at 22:11

0 Answers0