stdin上Java和C ++ app之间的通信问题

时间:2009-06-17 14:35:41

标签: java c++ select stdin fgets

我这里有一个java应用程序,它通过java.lang.Process API启动一个C ++应用程序,然后尝试通过stdin管道向它发送命令:

process.getOutputStream().write("foo\n");
process.getOutputStream().flush();

在C ++方面,有一个循环运行,它检查stdin中的输入,如果有的话 它读了它。不幸的是,检查总是返回0,因此它永远不会尝试读取。如果我删除了支票,那么它会突然开始看到命令并处理它们。这是在Linux上。

要检查和读取stdin的C ++应用程序代码是:

fd_set fds;
FD_ZERO ( &fds );
FD_SET ( 0, &fds );

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;


if( select ( 1, &fds, 0, 0, &tv ) > 0 ) {
    char buf[16384];
    buf[16383] = '\0';
    if ( fgets ( buf, sizeof ( buf ) - 1, stdin ) == 0 )
        return;
}

正如我所说,删除if子句会使它工作,但当然这不太好,因为它周围的循环也做了一些其他事情。有谁知道我在这里做错了什么?

更新: 同时我能用两个非常小的示例应用程序重现问题。这个问题似乎与Qt框架有关,一旦我创建了框架所需的QCoreApplication实例,那么stdin的select()似乎不再起作用了。

5 个答案:

答案 0 :(得分:1)

你有两个if;删除哪一个使它工作?

fgets()在返回之前是否等待换行符,缓冲区已满或EOF?我没有看到你写一个换行符,“foo”没有填充缓冲区,并且由于流没有关闭,它是否看到了EOF?

答案 1 :(得分:0)

我可能错了,但select通话的超时时间是否合理?我会尝试增加超时值。

答案 2 :(得分:0)

我记得有很多关于select()的语义和操作以及它的几个替换的争论。你可以看看那些。

您正在阅读的流如何创建/打开?它是缓冲流吗?也许你什么也得不到,因为在写入过程冲刷之前它还没有被写入流中?

你可能尝试的另一件事是将它放在一个阻塞I / O而不是轮询的线程上。

祝你好运

答案 3 :(得分:0)

原来它不是QCoreApplication,因为我现在可以用out重现问题两次。似乎问题是我正在使用的fgets(),用read()替换它会修复它。

答案 4 :(得分:0)

下面是while循环吗?如果没有,那应该是。

FD_ZERO ( &fds );
FD_SET ( 0, &fds );

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;

如果我的第一个问题的答案是肯定的,那么请尝试此超时:

tv.tv_sec = 0;
tv.tv_usec = 1;

如果上述方法不起作用,请尝试以下方法:

while(fgets(buf, sizeof ( buf ) - 1, stdin) !=NULL) 
{ 
}