Связь между Bash и Java с каналами: отправка в конце передачи - PullRequest
3 голосов
/ 13 февраля 2012

Я бы хотел настроить приложение Java, которое работает как сервер, принимая (блокируя) запросы из скрипта Bash.Часть Java написана с использованием nio и имеет основной цикл, который выглядит следующим образом:

ServerSocketChannel ssc = ...; // bound to localhost:8011
Charset charset = ...;

// Waits for connections forever.
while(true) {
  SocketChannel sc = ssc.accept();
  StringBuffer sb = new StringBuffer();
  int read = 0;
  // Builds up a string representing the query.
  while(true) {
    ByteBuffer bb = ByteBuffer.allocate(1024);
    read = sc.read(bb);
    if(read == -1) break;
    bb.flip();
    CharBuffer cb = charset.decode(bb);
    sb.append(cb.toString());
  }
  // Do something with the query.
  sc.write(charset.encode(CharBuffer.wrap(sb.toString())));
  sc.close();
}

Часть Bash опирается на магию /dev/tcp/:

exec 3<> /dev/tcp/localhost/8011
echo "message" 1>&3

Iможно увидеть, что сообщение, отправленное из Bash, достигает части Java (если я добавлю System.out.println(cb); во внутренний цикл, я смогу увидеть части), но внутренний цикл не завершится, если я не уничтожу скрипт Bash.

Мой вопрос на самом деле довольно прост: как скрипт Bash может сигнализировать серверу Java, что его связь завершена?Я пытался добавить

echo -en "\004" 1>&3 

в мой скрипт Bash, но это не помогло.

Ответы [ 2 ]

1 голос
/ 14 февраля 2012

То, чего я пытаюсь добиться, это заставить Java думать, что общение на данный момент завершено, но может возобновиться позже.

Вам необходимо понять, что это требование противоречитс точки зрения.Либо сообщение закончилось , либо , оно может возобновиться позже.В TCP нет ничего, что поддерживало бы это, поэтому в Java тоже ничего нет.

1 голос
/ 13 февраля 2012

Попробуйте закрыть дескриптор файла.Это должно рассматриваться Java как закрытый поток, и позволить внутреннему циклу завершиться.

exec 3>&-

Возможно, сокет может быть «полуоткрыт» (то есть отключен в одном направлениино все же открываю в другом).Экземпляр Socket имеет методов для обнаружения этого состояния.

Я не проверял, поддерживает ли гибрид труба-сокет, созданный bash, это или нет.Если этого не произойдет, вам придется разработать протокол с некоторыми внутренними последовательностями кодирования или разграничения длины для указания границ сообщения.

...