Странные исключения Socket: сброс соединения и тайм-аут соединения - PullRequest
3 голосов
/ 06 февраля 2011

У меня есть сервер Java TCP и клиент Android TCP.Сервер ожидает запросов и затем отправляет 50 МБ данных клиенту Android (который читает, зацикливая массив и перезаписывая данные, чтобы данные не сохранялись на телефоне.) Все работает нормально и модно, но в случайные моменты времени происходит сбой клиентас этим:

java.net.SocketException: Connection timed out

и сервер получает это:

java.net.SocketException: connection reset

Клиент читает в цикле, пока он не получил все данные (максимум, что я позволяю ему читать в одномВызов составляет 1,5 МБ.

Сервер отправляет так:

connectionSocket.getOutputStream().write(new byte[1024*1024*10*5]);

Я зацикливаю клиента и пытаюсь выполнить эту передачу 5-10 раз, чтобы я мог измерить время автономной работы, но яредко получаю 3 успешных завершения передачи 50 МБ. Я действительно в растерянности ... У меня действительно очень простая установка. Я готов опубликовать код, если это поможет.

Вот что adb logcatговорит для Android при сбое:

...transfering
D/WifiService(  109): got ACTION_DEVICE_IDLE
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
V/WifiMonitor(  109): Event [CTRL-EVENT-STATE-CHANGE id=1 state=8]
V/WifiStateTracker(  109): Changing supplicant state: COMPLETED ==> DORMANT
D/WifiStateTracker(  109): Reset connections and stopping DHCP
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
E/wpa_supplicant(  209): Set_key: Wrong Key
V/WifiMonitor(  109): Event [CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys]
V/WifiMonitor(  109): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=8]
D/WifiStateTracker(  109): Disabling interface
D/NetworkStateTracker(  109): setDetailed state, old =CONNECTED and new state=IDLE
V/WifiMonitor(  109): Event [CTRL-EVENT-DRIVER-STATE STOPPED]
V/WifiStateTracker(  109): New network state is DISCONNECTED
V/WifiStateTracker(  109): Changing supplicant state: DORMANT ==> DORMANT
D/ConnectivityService(  109): ConnectivityChange for WIFI: DISCONNECTED/IDLE
D/ConnectivityService(  109): getMobileDataEnabled returning false
D/ConnectivityService(  109): not failing over to mobile type 0 because Mobile Data Disabled
D/ConnectivityService(  109): not failing over to mobile type 2 because Mobile Data Disabled
D/ConnectivityService(  109): not failing over to mobile type 3 because Mobile Data Disabled
D/ConnectivityService(  109): not failing over to mobile type 4 because Mobile Data Disabled
D/ConnectivityService(  109): not failing over to mobile type 5 because Mobile Data Disabled
D/Tethering(  109): Tethering got CONNECTIVITY_ACTION
D/Tethering(  109): MasterInitialState.processMessage what=3
E/HierarchicalStateMachine(  109): TetherMaster - unhandledMessage: msg.what=3
I/ActivityManager(  109): Start proc android.process.media for broadcast com.android.providers.downloads/.DownloadReceiver: pid=793 uid=10004 gids={1015, 2001, 3003}
D/NetworkLocationProvider(  109): updateNetworkState(): Updating network state to 1
I/ActivityThread(  793): Publishing provider media: com.android.providers.media.MediaProvider
V/MediaProvider(  793): Attached volume: internal
V/MediaProvider(  793): /mnt/sdcard volume ID: 845505849
V/MediaProvider(  793): Attached volume: external
I/ActivityThread(  793): Publishing provider downloads: com.android.providers.downloads.DownloadProvider
I/ActivityThread(  793): Publishing provider drm: com.android.providers.drm.DrmProvider
I/GTalkService(  243): [ServiceAutoStarter] --- connectivity changed
I/GTalkService(  243): [ServiceAutoStarter] --- start GTalk service ---
I/ActivityManager(  109): Start proc com.google.android.apps.uploader for broadcast com.google.android.apps.uploader/.ConnectivityBroadcastReceiver: pid=801 uid=10027 gids={3003}
D/GTalkService(  243): [GTalkService.1] onStartCommand: found 0 connections, force audit connections...
D/GoogleLoginService(  243): onBind: Intent { act=android.accounts.AccountAuthenticator cmp=com.google.android.gsf/.loginservice.GoogleLoginService }
W/GoogleLoginService(  243): Device has no accounts: sending Intent { act=com.google.android.gsf.LOGIN_ACCOUNTS_MISSING }
D/GTalkService(  243): [GTalkService.25] account missing
I/ActivityThread(  801): Publishing provider com.google.android.apps.uploader: com.google.android.apps.uploader.UploadsContentProvider
I/ActivityThread(  801): Publishing provider com.google.photos.provider.Album: com.google.android.apps.uploader.clients.picasa.AlbumProvider
D/MediaUploader(  801): UploaderApplication.onCreate
D/MediaUploader(  801): nonWifiLimit=20971520, default=20971520
I/MediaUploader(  801): No need to wake up
I/ActivityManager(  109): Process com.google.android.apps.genie.geniewidget (pid 442) has died.
W/ActivityManager(  109): Scheduling restart of crashed service com.google.android.apps.genie.geniewidget/.GenieRefreshService in 5000ms
I/IO exception (  766): ******************** Log Msg IOE java.net.SocketException: Connection timed out
**W/System.err(  766): java.net.SocketException: Connection timed out
W/System.err(  766):    at org.apache.harmony.luni.platform.OSNetworkSystem.readSocketImpl(Native Method)
W/System.err(  766):    at org.apache.harmony.luni.platform.OSNetworkSystem.read(OSNetworkSystem.java:358)
W/System.err(  766):    at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:561)
W/System.err(  766):    at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:88)
W/System.err(  766):    at com.mdog.datareceive.Receive$1.onReceive(Receive.java:71)
W/System.err(  766):    at android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:892)
W/System.err(  766):    at android.os.Handler.handleCallback(Handler.java:587)
W/System.err(  766):    at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err(  766):    at android.os.Looper.loop(Looper.java:123)
W/System.err(  766):    at android.app.ActivityThread.main(ActivityThread.java:4627)
W/System.err(  766):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(  766):    at java.lang.reflect.Method.invoke(Method.java:521)
W/System.err(  766):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
W/System.err(  766):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
W/System.err(  766):    at dalvik.system.NativeStart.main(Native Method)**
I/ActivityManager(  109): Start proc com.google.android.apps.genie.geniewidget for service com.google.android.apps.genie.geniewidget/.GenieRefreshService: pid=811 uid=10031 gids={3003, 1015}

Вот исключение сервера:

Exception in thread "main" java.net.SocketException: Connection reset
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:96)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:124)
    at com.mdog.tcpserver.ServerDriver.main(ServerDriver.java:55)

Ответы [ 3 ]

2 голосов
/ 06 февраля 2011

Существуют различные причины, по которым разрывается соединение, начиная от инфраструктуры (как указал Дэн) до перехода устройства в спящий режим.Возможно, вы захотите попробовать запросить wakelock и посмотреть, поможет ли это.Кроме того, при случайном нажатии сенсорного экрана, чтобы удержать устройство в спящем режиме, можно увидеть, связано ли это со сном.

С другой стороны, если вы просто поймаете исключение и сразу же подключитесь и повторите попытку, ваши измерения не должныслишком много.Вы также можете попробовать UDP вместо TCP (таймауты невозможны).Обязательно контролируйте, если пропускная способность падает, хотя.

1 голос
/ 07 марта 2012

У меня возникла та же проблема, так как я загружаю тяжелые данные, которые занимают более 10 минут.Когда устройство перешло в режим сна, я получил java.net.SocketException: Connection timed out.

. Я попробовал решение, указанное @Michael, используя WakeLock во время загрузки.Это не устранило полную проблему для меня, потому что, если пользователь нажал кнопку питания, у меня возникла та же проблема.Если не нажималось, это работало, потому что вы мешали Android спать с WakeLock, а Wi-Fi не был выключен ...

Наконец, я обнаружил, что проблема не в том, что процессор спит, а в том, чтоWi-Fi выключен, когда экран выключается.Итак, Я использовал WifiLock, и это устранило проблему!

Мой код для работы с WakeLocks выглядит так (конечно, я выполняю фактическую работу в AsyncTask - воспринимаю его как псевдокод):

WifiManager wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
WifiLock wifiLock = wifiManager.createWifiLock("long_download");
wifiLock.acquire();
// Do the heavy work in background
wifiLock.release();

Вам потребуется следующее разрешение в AndroidManifest:

<uses-permission android:name="android.permission.WAKE_LOCK"/>
0 голосов
/ 06 февраля 2011

Просто угадай, но я не думаю, что это твой код;Я думаю, что это проблема сети.Я знал некоторые WiFi-роутеры (* кашель * Linksys * кашель *) , у которых были проблемы с обработкой такого количества данных за один раз.Попробуйте отключить WiFi и протестировать с 3G.Или, поскольку ваша цель состоит в том, чтобы проверить срок службы батареи, а не пропускную способность, попробуйте разбить записи данных на более мелкие порции с короткой паузой между каждым порциями (скажем, порциями по 100 КБ, с задержками от 10 до 100 мс.)немного исказите результаты своего теста, но вы можете достаточно легко учесть это, учитывая потребление батареи в течение общей продолжительности этих (предположительно простаивающих) пауз.

...