3

我有一个 Java TCP 服务器和一个 Android TCP 客户端。服务器等待请求,然后将 50MB 的数据发送到 Android 客户端(通过循环数组并覆盖数据进行读取,因此数据不会保存在手机上。)一切正常且花花公子,但客户端随机崩溃有了这个:

java.net.SocketException: Connection timed out

服务器得到这个:

java.net.SocketException: connection reset

客户端循环读取,直到收到所有数据(我允许它在一次调用中读取的最大值为 1.5MB。

服务器发送如下:

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

我正在循环客户端并尝试执行此传输 5-10 次,以便进行电池寿命测量,但我很少成功完成 3 次 50MB 传输。我真的很茫然......我的设置真的很简单。如果有帮助,我愿意发布代码。

这是 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)
4

3 回答 3

3

连接断开的原因有很多,从基础设施(正如 Dan 指出的)到设备进入睡眠状态。您可能想尝试请求唤醒锁,看看是否有帮助。此外,通过随机按下触摸屏来阻止设备进入睡眠状态,可以查看这是否与睡眠有关。

另一方面,如果您只是捕获异常并立即重新连接并重试,那么您的测量值不应该偏离太多。您可能还想尝试使用 UDP 而不是 TCP(不可能有超时)。请务必监控吞吐量是否下降。

于 2011-02-06T14:22:03.913 回答
1

我遇到了同样的问题,因为我下载了大量数据需要 10 多分钟。当设备进入睡眠状态时,我得到了java.net.SocketException: Connection timed out.

我尝试了@Michael 所述的解决方案,WakeLock在下载过程中使用了 a 。这并没有解决我的全部问题,因为如果用户按下电源按钮,我也会遇到同样的问题。如果它没有被按下,那是因为你阻止了 Android 进入睡眠状态WakeLock并且 Wifi 没有关闭......

最后,我发现问题不在于 CPU 休眠,而是屏幕关闭时 wifi 被关闭。所以我使用了 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"/>
于 2012-03-07T15:41:40.007 回答
0

只是猜测,但我认为这不是您的代码;我觉得是网络问题。我知道一些 WiFi 路由器(*cough* Linksys *cough*)在一次处理这么多数据时遇到了麻烦。尝试禁用 WiFi 并使用 3G 进行测试。或者,由于您的目的是测试电池寿命而不是吞吐量,请尝试将数据写入分成更小的块,每个块之间有一个短暂的暂停(例如,100K 块,延迟大约 10 到 100 毫秒。)这可能稍微歪曲您的测试结果,但您可以通过在这些(可能是空闲)暂停的总持续时间内考虑电池消耗来轻松地解释这一点。

于 2011-02-06T04:16:23.700 回答