Чтобы проверить отправку данных с помощью 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|
Приложение My 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 ( );
}