为什么使用QProcess从stdout读取会破坏我的Windows应用程序?

时间:2016-09-22 14:54:19

标签: c++ windows qt networking qprocess

我有一个跨平台(Windows 8 / OSX 10.10)测试应用程序,作为测试的一部分,需要生成一个将侦听端口的子进程(可以是动态的或指定的)。子进程(称之为MockServer)在启动时会向stdout发送一行如下所示:

Server listening on localhost:50015

在生成模拟服务器的代码中,我这样做:

//  globals
QProcess ServerMockProcess;
QString ServerPort

void
startServerMock()
{
    ServerMockProcess.start(SERVER_MOCK_EXE);
    ServerMockProcess.waitForReadyRead(2000);
    char buf[1024];
    qint64 lineLength = ServerMockProcess.readLine(buf, sizeof(buf));
    QString output;
    int port = 0;
    if (lineLength != -1) {
        output = buf;
        std::cout << output << std::endl;

        // A successful startup will produce output that looks like:
        // Server listening on localhost:50015
        ServerPort = output.section(":", -1);
        ServerPort.chop(1); // remove newline
        port = ServerPort.toInt();
    }

    if (!port) {
        QString msg = "Couldn't start " SERVER_MOCK_EXE ": " + output;
        std::cerr << msg << std::endl;
        throw FILESYSTEM_EXCEPTION(msg);
    }
    std::cout << "Talking to " << ServerPort << std::endl;
}

在这两个平台上,上面的代码似乎都有效 - 我看到在调用此函数时会出现两行,例如:

Server listening on 127.0.0.1:53869

Talking to 53869

随后,我调用将导致测试应用程序与服务器应用程序通信的代码(在这种情况下使用GRPC)。 SERVER_MOCK_EXE可以使用指定端口的命令行参数,或者如果留空,则动态选择一个(stdout通告端口)。在OSX上,此代码可以正常工作。但是,在Windows上,尝试打开GRPC连接会导致以下错误:

E0922 07:43:07.436000000  6420 resolve_address_windows.c:99] getaddrinfo: The specified class was not found.

D0922 07:43:07.436000000  6420 dns_resolver.c:186] dns resolution failed: retrying in 1.000000000 seconds
E0922 07:43:08.440000000  5296 resolve_address_windows.c:99] getaddrinfo: The specified class was not found.

D0922 07:43:08.441000000  5296 dns_resolver.c:186] dns resolution failed: retrying in 1.773000000 seconds
E0922 07:43:10.218000000  1752 resolve_address_windows.c:99] getaddrinfo: The specified class was not found.

D0922 07:43:10.219000000  1752 dns_resolver.c:186] dns resolution failed: retrying in 2.841000000 seconds

经过多次实验,我发现破坏服务器的是读取stdout来获取端口。如果我改为对端口进行硬编码并将其传入,则可以通过以下方式与服务器进程通信:

void
startServerMock()
{
    ServerMockProcess.start(SERVER_MOCK_EXE " 53869");
    ServerMockProcess.waitForReadyRead(2000);
    ServerPort = "53869";
    std::cout << "Talking to " << ServerPort << std::endl;
}

它不仅仅是破坏它的动态端口分配,因为用行调用函数的第一个版本

    ServerMockProcess.start(SERVER_MOCK_EXE " 53869");

而不是将其留空仍然会导致上面的网络错误。

有什么想法吗?

0 个答案:

没有答案