无法可靠地写入控制台应用程序

时间:2016-01-26 13:19:00

标签: java processbuilder linphone

我正在调用linphonec.exe,这是一个用于控制Linphone的交互式控制台应用程序,这是一个在Windows 7上通过Java(1.8u11)开源的类似Skype的应用程序。

在Linphone 3.8.2中一切正常,但是在更新到3.9.1之后,我再也无法可靠地从Java调用命令进入应用程序,一些命令被处理,一些命令被默默忽略。

重新创建,发出帮助命令的小例子。

public class CommandTest {
    private static class Consumer implements Runnable {
        private InputStream stream;
        public Consumer(InputStream stream) {
            this.stream = stream;
        }
        @Override
        public void run() {
            int c = 0;
            try {
                while ((c = stream.read()) != -1) {
                    System.out.print((char) c);
                }
                System.out.println("Stream finish");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ProcessBuilder builder = new ProcessBuilder(
                Arrays.asList("C:\\Program Files (x86)\\Linphone\\bin\\linphonec.exe"));
        builder.redirectInput(Redirect.PIPE);
        Process process = builder.start();
        new Thread(new Consumer(process.getInputStream())).start();
        new Thread(new Consumer(process.getErrorStream())).start();
        BufferedWriter stdin = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), StandardCharsets.US_ASCII));
        stdin.write("help\n");
        stdin.flush();
        process.waitFor();
    }
}

输出 - 用3.8.2

Ready
Warning: video is disabled in linphonec, use -V or -C or -D to enable.
linphonec> Commands are:
---------------------------
      help  Print commands help.
      call  Call a SIP uri or number
      ... etc... 

输出 - 3.9.1

Ready
linphonec> linphonec> 

分析

  • 问题缩小到linphonec.exe的输出,似乎它正在响应命令,但那些没有及时刷新到标准输出

  • 例如,以下内容确实有效,但是只有在运行了一些帮助命令后才能得到结果,我只能假设这意味着子进程的输出缓冲区已达到某个级别,在这种情况下自动刷新

代码

stdin.write("webcam list\n");
stdin.flush();
Thread.sleep(100);
stdin.write("webcam list\n");
stdin.flush();
Thread.sleep(100);
stdin.write("webcam list\n");
stdin.flush();
Thread.sleep(100);
stdin.write("webcam list\n");
stdin.flush();
Thread.sleep(100);
stdin.write("help\n");
stdin.flush();
Thread.sleep(100);
stdin.write("help\n");
stdin.flush();
Thread.sleep(100);
stdin.write("help\n");
stdin.flush();
Thread.sleep(100);
stdin.write("help\n");
stdin.flush();

输出

linphonec> linphonec> linphonec> linphonec> linphonec> linphonec> linphonec> linphonec> Warning: video is disabled in linphonec, use -V or -C or -D to enable.
0: StaticImage: Static picture
0: StaticImage: Static picture
0: StaticImage: Static picture
0: StaticImage: Static picture
Commands are:
---------------------------
      help  Print commands help.
    answer  Answer a call
autoanswer  Show/set auto-answer mode
      call  Call a SIP uri or number
  • 这个结论得到了以下事实的支持:警告:在linphonec中禁用视频,使用-V或-C或-D启用。只是稍后打印,即使它在主循环开始之前在主init()方法中写入。此行在3.8.2中立即显示,但仅在3.9.1
  • 中刷新stdout缓冲区之后

linphone来源分析

大多数输出​​,比如帮助等都在linphonec.c中使用linphonec_out,这有一个明确的fflush()但似乎不起作用......

char *res;
va_list args;
va_start (args, fmt);
res=ortp_strdup_vprintf(fmt,args);
va_end (args);
printf("%s",res);
fflush(stdout);

问题

  • 为什么在3.8.2中立即发生冲洗,而在3.9.1
  • 中不发生冲洗
  • 我在Java中做了明显错误的事情
  • 使用这种方法和最近版本的Linphone Desktop ...
  • ,任何人都可以成功地与Java集成

0 个答案:

没有答案