I have a cross-platform (Windows 8/OSX 10.10) test application which, as part of the test, needs to spawn a child process which will listen on a port (can be dynamic or specified). The child process (call it MockServer), upon startup, will send to stdout a line that looks like:
Server listening on localhost:50015
In the code that spawns the mock server, I'm doing this:
// 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;
}
On both platforms, the code above appears to work - I see a two lines appear when this function is called, e.g.:
Server listening on 127.0.0.1:53869
Talking to 53869
Subsequently, I invoke code that will cause the test application to talk to the server application (using GRPC, in this case). The SERVER_MOCK_EXE can take a command line argument specifying a port, or if left blank, it dynamically chooses one (with the stdout advertising the port). On OSX, this code works correctly. However, on Windows, attempting to open a GRPC connection results in these errors:
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
After much experimentation, I discovered that what was breaking the server was the reading of stdout to get the port. If I instead hard-coded a port and passed it in, the server process could be communicated with:
void
startServerMock()
{
ServerMockProcess.start(SERVER_MOCK_EXE " 53869");
ServerMockProcess.waitForReadyRead(2000);
ServerPort = "53869";
std::cout << "Talking to " << ServerPort << std::endl;
}
It isn't just the dynamic port allocation that is breaking it, since invoking the first version of the function with the line
ServerMockProcess.start(SERVER_MOCK_EXE " 53869");
instead of leaving it blank still results in the networking errors above.
Any ideas?