【问题标题】:howto force socket.close to release write block如何强制 socket.close 释放写块
【发布时间】:2012-01-26 22:04:32
【问题描述】:

当我进行文件传输并且设备失去互联网连接时
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) {

                }
        }
     }

}
};

【问题讨论】:

    标签: java android sockets ftp blocking


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我更新了我的问题。运行测试和阻塞不会松手。不会 DataOutputStream.close() 工作吗? Socket 是 IntentService 类中的一个字段,Socket 从 onHandleIntent() 传递给工作线程
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2015-10-25
    • 1970-01-01
    • 2016-12-24
    • 2015-09-15
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多