如何强制socket.close释放写块

时间:2012-01-26 22:04:32

标签: java android sockets ftp blocking

当我有文件传输并且设备丢失互联网连接时 DataOutputStream.write有时几乎无法阻挡。

我知道这是正常的,因为底层套接字层正在尽可能快地完成它的工作。

我正在考虑使用

registerReceiver(mConnRec,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

并在发生这种情况时抓住并执行socket.close()DataOutputStream.close()
强制DataOutputStream.write停止阻止并发生正常的代码流 更快。

这会起作用吗或我该如何控制阻止?

我的另一个想法是开始一个每5秒工作一次的线程 测试互联网就像这样存在

public boolean haveNetworkConn(Context ctx)
{
    boolean HaveConnectedWifi = false;
    boolean HaveConnectedMobile = false;

    ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] netInfo = cm.getAllNetworkInfo();

    for (NetworkInfo ni : netInfo)
    {
        if (ni.getTypeName().equalsIgnoreCase("WIFI"))
            if (ni.isConnected())
                HaveConnectedWifi = true;
        if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
            if (ni.isConnected())
                HaveConnectedMobile = true;
    }
    return HaveConnectedWifi || HaveConnectedMobile;
} 

如果返回false,我可以强制执行socket.close。

真的想对这个想法有一些反馈

更新 使用registerReceiver BroadcastReceiver运行一些测试 当我关闭OutputStream和套接字本身的数据时没有任何反应。 它在out.write(buffer, 0, val);处继续阻止。这是最意想不到的 使用Eclipse并放置断点和步进..

private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {

     String action = intent.getAction();

     if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)){
         return;
     }

     boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 
     NetworkInfo aNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);                     

     if (!noConnectivity)
     {
         if ((aNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) || (aNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI))
         {
             //Handle connected case
         }
     }
     else
     {
        if ((aNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) || (aNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI))
        {
            //Handle disconnected case
            if(socket != null)
                try {
                    out.close();
                    in.close();
                    socket.close();

                } catch (IOException e) {

                }
        }
     }

}
};

1 个答案:

答案 0 :(得分:2)

是的,关闭套接字是一种解除当前在套接字上阻止的方法调用的方法。引自the documentation for close()

  

此套接字上的I / O操作中当前阻塞的任何线程都将   抛出一个SocketException。

另请参阅“实践中的Java并发”一节中的第7.1.6节。

CONNECTIVITY_ACTION注册接收器是一个比每5秒轮询一次更好的解决方案,因为它可以节省CPU周期,并可能在应用程序对连接变化的反应中提供更好的延迟。