要使用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
:
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 ( );
}
答案 0 :(得分:0)
最后,我发现原因是:
bb.wrap ( cache );
解决方案是替换为:
bb.put ( cache ).flip ( );