2

Android で localsockets を使用する。別の接続から読んでいるユーザーがいます。接続は、ソケットを閉じ、入力ストリームを閉じ、そのスレッドを中断することにより、読み取りを停止するように指示されます。もう一方の端がシャットダウンするまで、読み取りの試行を停止しません。では、とにかく読み取りを中断させる方法はありますか?

これは私の問題の非常に単純化された例です。チャネルを使用しようとすると、問題はさらに深刻になります。スレッド/チャネルでの割り込み/クローズ要求を (それぞれ) ブロックします。

このログを取得する必要があります。

V/test    ( 4416): bound
V/test    ( 4416): accepted
V/test    ( 4416): stop
V/test    ( 4416): stop exit
V/test    ( 4416): closing
V/test    ( 4416): done reading?
V/test    ( 4416): all closed

クラス 1:

public class Runner1 implements Runnable
{

public static Runner1       me  = null;

public InputStream          in;
public ReadableByteChannel  rb;
LocalSocket                 ls;
public Thread               thisThread;

public Runner1() {
    me = this;
}

@Override
public void run()
{
    thisThread = Thread.currentThread();
    try
    {
        LocalServerSocket lss = new LocalServerSocket(Test2Activity.location);
        ls = lss.accept();
        Log.v("test", "accepted");

        in = ls.getInputStream();
        byte[] buffer = new byte[10];
        in.read(buffer);
        // rb = Channels.newChannel(in);

        // ByteBuffer bb = ByteBuffer.allocate(100);
        // rb.read(bb);
        Log.v("test", "done reading?");
        ls.close();
        lss.close();
        Log.v("test", "all closed");
    }
    catch (IOException e)
    {
        Log.v("test", "error1");
        e.printStackTrace();
    }
}

public static void stop()
{
    Log.v("test", "stop");
    try
    {
        // me.rb.close();
        me.in.close();
        me.ls.close();
        // me.ls.shutdownInput();
        // me.ls.shutdownOutput();
    }
    catch (IOException e)
    {
        Log.v("test", "error - stop" + e.toString());
        e.printStackTrace();
    }

    me.thisThread.interrupt();

    Log.v("test", "stop exit");
}
}

クラス 2:

public class Runner2 implements Runnable
{
@Override
public void run()
{

    try
    {
        sleep(1500);
        LocalSocket ls = new LocalSocket();
        ls.connect(new LocalSocketAddress(Test2Activity.location));
        Log.v("test", "bound");
        WritableByteChannel wc = Channels.newChannel(ls.getOutputStream());
        sleep(3000);
        Runner1.stop();
        sleep(4000);
        Log.v("test", "closing");
        ls.close();
    }
    catch (IOException e)
    {
        Log.v("test", "error" + e.toString());
        e.printStackTrace();
    }
}

public void sleep(int time)
{
    try
    {
        Thread.sleep(time);
    }
    catch (InterruptedException e1)
    {
    }
}
}
4

2 に答える 2

0

入力用のソケットをシャットダウンするだけです。これにより、EOS が read() に渡されます。読み取りスレッドは、ソケット自体を閉じて終了する必要があります。これは、既にコーディングされているはずです。

于 2013-10-14T23:36:46.773 に答える
0

これを回避するために私が見つけた最善のハックは、タイムアウトを設定し、ソケットが別のスレッドで閉じられているかどうかを確認することでした。

残念ながら、タイムアウトを設定しても TimeoutException は発生しません:(

于 2013-10-14T21:21:54.997 に答える