Использование поддержки гнезда домена JDK16+ Unix для подключения к Clamd случайным образом сбое для соединения N-Th (n>JAVA

Программисты JAVA общаются здесь
Anonymous
Использование поддержки гнезда домена JDK16+ Unix для подключения к Clamd случайным образом сбое для соединения N-Th (n>

Сообщение Anonymous »

Я пытаюсь подключиться к службе Clamd (антивирус) в системе Ubuntu Linux. Clamd на Ubuntu Linux можно связаться с использованием домена Unix, который по умолчанию зарегистрирована под Path /var/run/clamav/clamd.ctl.
Доступ к этому сокету из Java с использованием UnixDomainescocketCocketDress Поддержка, добавленная в jdk16+, когда соответствующий SockeTectle -Anallanel. Для базового теста связи используется команда Clamd Ping, которая заставляет сервер отвечать на поннг. В режиме блокировки 100 подключений, где протестированы последовательно и работали OK (то есть все получили поннг). При переключении в режим не блокировки первое соединение всегда работает, но последующие подключения проваливаются. Иногда первые несколько подключений работают. < /P>
Использование не блокирующего io имеет цель, чтобы иметь возможность применять тайм-аут для операций, выполненных в Clamd. < /P>
Это тестовый код, который я использую: < /p>

Код: Выделить всё

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.ProtocolFamily;
import java.net.SocketAddress;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;

import static java.nio.charset.StandardCharsets.UTF_8;

public class ClamdTest3 {

private static final byte[] PING_CMD = "zPING\0".getBytes(UTF_8);

public static void main(String[] args) throws IOException {
ProtocolFamily protocolFamily = StandardProtocolFamily.UNIX;
SocketAddress socketAddress = UnixDomainSocketAddress.of("/var/run/clamav/clamd.ctl");
for (int i = 0; i < 100; i++) {
try (SocketChannel socketChannel = SocketChannel.open(protocolFamily);
Selector selector = Selector.open();) {
socketChannel.configureBlocking(false);
socketChannel.connect(socketAddress);
SelectionKey selectionKey = socketChannel.register(selector, 0);
selectionKey.interestOps(SelectionKey.OP_CONNECT);
selectionKey.selector().select(10_000);
if (!socketChannel.finishConnect()) {
throw new IOException("Connection failed");
}
System.out.println("Connected connection: " + i);
writeToChannel(socketChannel, selectionKey, ByteBuffer.wrap(PING_CMD), 5000);
System.out.println(new String(readFromChannel(socketChannel, selectionKey, 10000), StandardCharsets.UTF_8));
}
}
}

private static byte[] readFromChannel(SocketChannel socketChannel, SelectionKey selectionKey, long timeout_milli) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
long start = System.nanoTime();
ByteBuffer bb = ByteBuffer.allocate(4096);
selectionKey.interestOps(SelectionKey.OP_READ);
while (socketChannel.read(bb) >= 0) {
bb.flip();
baos.write(bb.array(), bb.position(), bb.limit() - bb.position());
if (bb.limit() > 0 && bb.get(bb.limit() - 1) == 0) {
break;
}
if (isTimeout(start, timeout_milli)) {
throw new IOException("Timeout while reading");
}
if (!selectionKey.isReadable()) {
selectionKey.selector().select(timeout_milli / 10);
}
}
return baos.toByteArray();
}

private static void writeToChannel(SocketChannel socketChannel, SelectionKey selectionKey, ByteBuffer bb, long timeout_milli) throws IOException {
long start = System.nanoTime();
selectionKey.interestOps(SelectionKey.OP_WRITE);
while (socketChannel.write(bb) >= 0) {
if (bb.position() >= bb.limit()) {
break;
}
if (isTimeout(start, timeout_milli)) {
throw new IOException("Timeout while writing");
}
if (!selectionKey.isWritable()) {
selectionKey.selector().select(timeout_milli / 10);
}
}
}

private static boolean isTimeout(long start, long timeout_milli) {
long timeout_nano = timeout_milli * 1000L * 1000L;
Long now = System.nanoTime();
Long timeoutComp = now - timeout_nano;
boolean isTimout = Long.compare(timeoutComp, start) > 0;
return isTimout;
}
}
Я и ожидал бы последовательность сообщений «подключенное соединение ... pong», которые начинаются с подключенного соединения: 0 и завершают 99 -е соединение.
Однако я наблюдаю:
Connected connection: 0
PONG
Connected connection: 1
PONG
Connected connection: 2
PONG
Connected connection: 3
Exception in thread "main" java.io.IOException: Timeout while reading
at ClamdTest3.readFromChannel(ClamdTest3.java:53)
at ClamdTest3.main(ClamdTest3.java:36)
< /code>
Пробое: < /p>
  • Добавление задержки после блока Try-Catch (Thread#Sleep, 1s, 10s), тот же результат < /li>
    Добавление явного вызова GC, тот же результат < /li>
    , чтобы открыть несколько SocketcheTch, чтобы не представить, что не в режиме, чтобы не представить, что не так уж и в режиме. на приемной стороне


Подробнее здесь: https://stackoverflow.com/questions/796 ... ails-for-t

Вернуться в «JAVA»