Reputation: 1220
Attempting to read from a named pipe. As far as I know the client is connecting ok and sending. Considering the code is taken from solutions on here, i'm struggling to see where I have messed up. Readfile doesn't seem to get anything. It doesn't return. If you close the connection at the client end 0 is returned.
Any Ideas?
DWORD WINAPI LogManager::LogCollector(LPVOID args)
{
LogMan *LogMgr = (LogMan*)args;
int run; LogMgr ->GetValue(run);
while (run != LogMan::eNONE) {
HANDLE pipe = CreateNamedPipe("\\\\.\\pipe\\RCLogPipe", PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
ConnectNamedPipe(pipe, NULL);
if (pipe == INVALID_HANDLE_VALUE){
CloseHandle(pipe);
return -1;
}
char line[1024];
DWORD numRead = 0;
if (!ReadFile(pipe, line, 1024, &numRead, NULL) || numRead < 1) return -1;
LogMgr ->Write(line);
LogMgr ->GetValue(run);
CloseHandle(pipe);
}
return 0;
}
Client
var client = new NamedPipeClientStream("RCLogPipe");
client.Connect();
StreamWriter writer = new StreamWriter(client);
if (client.CanWrite) writer.WriteLine("Hello\n");
Upvotes: 1
Views: 1697
Reputation: 12425
C#'s StreamWriter will probably buffer until a flush occurs, so you answered your own first question there. C# doesn't null-terminate strings (and neither does ReadFile - it doesn't assume anything about the data you're reading, for all it could care your data could be binary), but you're using the data you get out of ReadFile like a c-string (null-terminated strings). So Write will see {'h' 'e' 'l' 'l' 'o' ' ' 'w' 'o' 'r' 'l' 'd' [arbitrary bytes]}. Write will continue reading through memory until it finds a null-character, at which point it stops. So all of the garbage is arbitrary crap until Write happens by chance to find a null character.
You need to use the numRead value to either pass it to Write to tell it how much of the buffer to look at, or use it to manually null-terminate your string - line[numRead] = '\0';
- assuming you have the room in the buffer.
Upvotes: 5