我有一个跨平台(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");
而不是将其留空仍然会导致上面的网络错误。
有什么想法吗?