簡體   English   中英

SocketChannel.read()僅獲得一次正確的數據,並且為空

[英]SocketChannel.read ( ) got correct data only once and blank

要使用SocketChannel測試發送數據,請執行以下操作:

我的Java應用程序使用SocketChannel.write()來重復發送相同的數據,並且會隨機延遲。 檢查cmdline日志,始終正確發送數據。

|2018|0|null|null|0|....000000|0.000000|
|2018|0|null|null|0|....000000|0.000000|
|2018|0|null|null|0|....000000|0.000000|
|2018|0|null|null|0|....000000|0.000000|
|2018|0|null|null|0|....000000|0.000000|

我的Kotlin應用程序通過SocketChannel.read()接收數據,並稍微打印日志。 使用初始化的SocketChannel mySocketChannel和Selector selector

while ( true ) {
    selector.select ( )
    val selectedKeys = selector.selectedKeys ( )
    selectedKeys.parallelStream ( )
        .forEach {
            when ( it.channel ( ) ) {
                mySocketChannel -> run {
                    if ( it.isReadable ( ) )
                    {
                        read@ while ( true )
                        {
                            input.position ( 0 )
                            val len = mySocketChannel.read ( input )
                            print ( "len=$len " )
                            when
                            {
                                len > 1 -> {
                                    input.position ( 0 );
                                    val data = ByteArray ( len )
                                    input.get ( data )
                                    println ( Calendar.getInstance ( ).toInstant ( ).toString ( ) + "\t" + data.size )
                                    println ( String ( data ).substring ( 0, 20 ) + "..." + String ( data ).substring ( data.size - 20 ) )
                                }
                                len < -1    -> {
                                    // dead connection
                                    println ( "Dead connection" )
                                    // unregister later
                                    break@read
                                }
                                else    -> {
                                    break@read
                                }
                            } // when: read from server
                        } // while: 1
                    } // if: readable
                }
                else -> { }
            } // when: readable channel
        } // foreach: selected keys
    selectedKeys.clear ( )
} // while: 1

連接仍然可以,但是問題是接收到的數據僅在第一次時是正確的,並且變為空白:

len=10000 2018-10-18T17:55:21.606Z      10000
|2018|0|null|null|0|....000000|0.000000|
len=0
len=10000 2018-10-18T17:55:30.119Z      10000
            ...
len=0 
len=10000 2018-10-18T17:55:30.625Z      10000
            ...
len=0 
len=10000 2018-10-18T17:55:31.131Z      10000
            ...
len=0 
len=10000 2018-10-18T17:55:32.136Z      10000
            ...

那么,發生了什么事?

編輯:

我使用Java接收器進行了測試,並且發生了相同的問題。 因此,讓我們看一下發送者的來源:

final byte [] cache = ( data + ( data.charAt ( data.length ( ) - 1 ) != '\n' ? "\n" : "" ) ).getBytes ( );

try {
    selector.selectNow ( );
    Set <SelectionKey> selectedKeys = selector.selectedKeys ( );
    selectedKeys.parallelStream ( ).forEach ( selectedKey -> {
        ByteBuffer bb = ByteBuffer.allocate ( cache.length );
        bb.wrap ( cache );
        System.out.print ( new String ( cache ).substring ( 0, 20 ) + "..." + new String ( cache ).substring ( cache.length - 20 ) );
        if ( selectedKey.isWritable ( ) )
        {
            try {
                int len = ( (SocketChannel) selectedKey.channel ( ) ).write ( bb );
            } catch ( IOException ioe ) {
                ioe.printStackTrace ( );
                // dead connection
                try { selectedKey.channel ( ).close ( ); } catch ( IOException ioe1 ) { }
            }
        }
    } );
    selectedKeys.clear ( );
} catch ( IOException ioe ) {
    ioe.printStackTrace ( );
}

最后,我發現原因是:

bb.wrap ( cache );

解決方案是替換為:

bb.put ( cache ).flip ( );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM