Задать вопрос
CTAKAH4uK
@CTAKAH4uK

AsynchronousSocketChannel не может дочитать ответ, в чем проблема?

Пытаюсь организовать опрос большого кол-ва устройств, в качестве подключения использую AsynchronousSocketChannel + AsynchronousChannelGroup, из-за большой нагрузки иногда данные приходят не полные, код :
Создание соединения :
AsynchronousChannelGroup group = AsynchronousChannelGroup
                .withFixedThreadPool(numThreads, Executors.defaultThreadFactory());

AsynchronousSocketChannel[] channels = 
                new AsynchronousSocketChannel[numToOpen];  

for (int i = 0; i < numToOpen; i++) { 
	ByteBuffer request = ByteBuffer.wrap(Config.MESSAGE);
	channels[i] = AsynchronousSocketChannel.open(group);
	channels[i].setOption(StandardSocketOptions.SO_RCVBUF, 65536);
	channels[i].setOption(StandardSocketOptions.SO_SNDBUF, 65536);
	channels[i].setOption(StandardSocketOptions.SO_REUSEADDR, true);
	channels[i].setOption(StandardSocketOptions.SO_KEEPALIVE, true);
	channels[i].connect(new InetSocketAddress(device.getIp(), Config.PORT), new BufferContainer(request, channels[i], device,xmlQueue), new ConnectHandler());
}

ConnectHandler :
public void completed(Void result, BufferContainer container) {
	container.channel().write(container.buffer(), container, new WriteHandler());		
}


WriteHandler
public void completed(Integer arg, BufferContainer container) {		
	if (container.buffer().hasRemaining()) {
		container.channel().write(
				container.buffer(), container, this);
		return;
	}	
	ByteBuffer readbuff = ByteBuffer.allocateDirect(65536);
	container.setBuffer(readbuff);
	container.channel().read(readbuff, container, new ReadHandler());
}


ReadHandler
public void completed(Integer result, BufferContainer container) {
	//Тут не приходит result=-1, если вызвать :
	//if(result != -1){
	//	container.channel().read(container.buffer(), container, this);
	//}
	// То второго вызова completed не происходит
	container.buffer().flip();
	strBuilder.append(charset.decode(container.buffer()));
	strBuilder.delete(0, 5);
	strBuilder.delete(strBuilder.length() - 2, strBuilder.length());
	container.getXmlQueue().add(new XMLData(container.device() , strBuilder.toString()));
}


Пробовал в ReadHandler, добавить Thread.sleep(), в этом случае данные почти всегда дочитываются до конца, но в разы урезается производительность.

Подскажите пожалуйста, с чем может быть связано получение не полных данных, и в какую сторону копать.
Заранее спасибо.
  • Вопрос задан
  • 2514 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
@ponkin
Могу только предположить что некоторые данные не "умещаются" во один внутренний буфер и поэтому
могут передаваться в 2,3,... вызова.
Прще говоря, надо где-то буфферезировать получаемые данные перед тем как их обрабатывать(не знаю что у вас там является индикатором конца сообщения по логике).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы