[英]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.