Bash和Java之间通过通道进行通信:发送传输结束

时间:2012-02-13 18:51:28

标签: java bash nio

我想设置一个充当服务器的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

我可以看到从Bash发送的消息确实到达Java部分(如果我在内部循环中添加System.out.println(cb);,我可以看到部分),但内部循环不会终止,除非我杀了Bash脚本。

我的问题非常简单:Bash脚本如何向Java服务器发出信号,告知其通信已经结束?我试过添加

echo -en "\004" 1>&3 

在我的Bash脚本中,但没有帮助。

2 个答案:

答案 0 :(得分:1)

尝试关闭文件描述符。这应该被Java视为封闭流,并允许内部循环终止。

exec 3>&-

套接字可以是“半开”(即,在一个方向上关闭但在另一个方向上仍然打开)。 Socket实例具有methods to detect此状态。

我还没有测试bash创建的管道插槽混合是否支持。如果没有,您将不得不设计一个带有一些内部长度编码或分隔序列的协议来指示消息边界。

答案 1 :(得分:1)

  

我想要实现的是让Java认为   通信现在已经结束,但可能会在稍后恢复。

您需要了解这一要求在术语上是矛盾的。通信已结束可能会在稍后恢复。 TCP中没有任何东西支持这一点,在Java中也没有任何东西。