简体   繁体   English

SocketChannel:中断关闭所有打开的通道

[英]SocketChannel: interrupt close all open channels

I have the following scenario: 我有以下情况:

  • A server open's a ServerSocketChannel and accept client connections. 服务器打开一个ServerSocketChannel并接受客户端连接。
  • Every connection (socketA) is handled in a new thread. 每个连接(socketA)在一个新线程中处理。
  • Inside the thread I open a new SocketChannel (socketB) which connects a another server. 在线程内部,我打开了一个新的SocketChannel(socketB),它连接了另一个服务器。
  • The original client connection (socketA) is idle at this time. 原始客户端连接(socketA)目前处于空闲状态。
  • The new SocketChannel reads data (blocking) from the server. 新的SocketChannel从服务器读取数据(阻塞)。

Now I interrupt the thread. 现在我中断线程。 I expected that socketB will be interrupted and closed and socketA will be continue to work. 我预计socketB将被中断并关闭,socketA将继续工作。 Unfortunately socketA will also be interrupted. 不幸的是,socketA也将被中断。

Any idea what could be the problem? 知道可能是什么问题吗?

I use the following test methods to reproduce the behavior: 我使用以下测试方法来重现该行为:

private void testServerSocket() throws IOException, InterruptedException
{
    final InetSocketAddress     address         = new InetSocketAddress( "localhost", 12345 );
    final ServerSocketChannel   serverChannel   = ServerSocketChannel.open();
    serverChannel.socket().bind( address );

    final SocketChannel socketChannel   = serverChannel.accept();

    // start communication in new thread
    final Thread    thread  = new Thread( new Runnable() { @Override public void run() { testWrite( socketChannel ); } } );

    thread.start();

    // wait a little bit
    Thread.sleep( 5000 );

    // interrupt thread, will interrupt the socketChannel.read in testRead()
    thread.interrupt();
    thread.join();

    socketChannel.close();
    serverChannel.close();
}

void testWrite( SocketChannel socketA )
{
    try
    {
        // write to client
        socketA.write( ByteBuffer.wrap( "0123456789".getBytes() ) );

        // open new socket to another server
        testRead();

        // throws ClosedByInterruptException
        socketA.write( ByteBuffer.wrap( "0123456789".getBytes() ) );
    }
    catch( final IOException e )
    {
        e.printStackTrace();
    }
}

void testRead()
{
    try
    {
        final InetSocketAddress address   = new InetSocketAddress( "localhost", 12346 );
        final SocketChannel     socketB   = SocketChannel.open( address );

        // server doesn't send, so this call will block and interrupted 
        socketB.read( ByteBuffer.wrap( new byte[10] ) );

        socketB.close();
    }
    catch( final IOException e )
    {
        e.printStackTrace();
    }
}

You need to clear the thread's interrupted state by calling Thread.interrupted() after the IOException in testRead() . 您需要通过在testRead()IOException之后调用Thread.interrupted()来清除线程的中断状态。 Actually you should catch ClosedByInterruptException and do it there. 实际上,您应该捕获ClosedByInterruptException并在那里执行。 Otherwise the condition persists and interrupts the write as well. 否则,条件仍然存在,并且也会中断写入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM