奇怪的SocketExceptions:连接重置和连接超时

时间:2011-02-06 04:09:42

标签: java android tcp client-server socketexception

我有一个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次转移,因此我可以进行电池寿命测量,但我很少能完成50次传输的3次成功完成。我真的很茫然......我的设置非常简单。我愿意发布代码,如果有帮助的话。

以下是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 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

我尝试了@Michael所说的解决方案,在下载过程中使用了WakeLock。这并没有解决我的全部问题,因为如果用户按下电源按钮我遇到了同样的问题。如果没有按下它是有效的,因为你阻止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"/>

答案 2 :(得分:0)

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