Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Client not reading from named pipe

Status
Not open for further replies.

KempCGDR

Programmer
Jan 10, 2003
445
GB
Hi, I've been putting together a server and client that use a named pipe to communicate (they both run on the same machine). The server creates the pipe and the client connects fine, then the client sends a message to the server which works fine as well (the server can print the message as it should be). That's where it starts to go wrong, the server replies to the client and the read operation on the client returns (it's set to be blocking), but it doesn't actually supply any data and the number of bytes read is set to 0. An abbreviated copy of my code is shown.

The server creates the pipe with this:
Code:
CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, sPIPE_BUFFER, sPIPE_BUFFER, 10000, NULL);

connected = ConnectNamedPipe(PipeHandle, NULL);

if (!connected) {
	connected = (GetLastError() == ERROR_PIPE_CONNECTED);
}

And then handles the client like this:
Code:
OpResult = ReadFile(PipeHandle, ClientRequest, sPIPE_BUFFER, &BytesRead, NULL);

if (OpResult && (BytesRead > 0))
{
	strcpy(Reply, "Example Response");
	ReplySize = (UINT)strlen("Example Response") + 1;
 
	OpResult = WriteFile(PipeHandle, Reply, ReplySize, &Written, NULL);
}

ProcessRequest returns the reply to send in the cunningly named Reply. This appears to be working this far as I can display the message properly (it isn't shown here but Reply and the other buffers in the code are defined as
Code:
char Whatever[BUFFER_SIZE]
And are zeroed before use.

So as far as I know, all that works. Now onto the client. The client does
Code:
PipeHandle = CreateFile(PipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (PipeHandle == INVALID_HANDLE_VALUE)
{
	MB("Error", "Unable to open pipe");
	return EXIT_FAILURE;
}
	
DWORD open_mode = (PIPE_READMODE_MESSAGE | PIPE_WAIT); 
if (!SetNamedPipeHandleState(PipeHandle, &open_mode, NULL, NULL)) 
{
	MB("Error", "Unable set pipe mode");
	return EXIT_FAILURE;
}

if (TransactNamedPipe(PipeHandle, Message, sPIPE_BUFFER, Buff, sPIPE_BUFFER, &Read, NULL) == 0)
{
	MB("Error", "Transaction Error");
	return EXIT_FAILURE;
}

This doesn't display any error messages, but Buff appears to be all null characters (presumably from it being zeroed before use) and Read is 0.

This has had me scratching my head for a while now, especially as it is nearly identical to the examples given on MSDN. Does anybody have any thoughts on this?
 
Possibly waiting for the buffer to be full before sending. After writing, add
Code:
FlushFileBuffers (PipeHandle);
 
I have tried this, and still nothing is received by the client. No matter how long the timeout period is set it still returns straight away with no data, which is impossible as far as I know what with it being set to blocking.

I find it really strange as the code to send to the server and for the server to send stuff back again is virtually identical and the server does receive the message from the client.

Also, TransactNamedPipe doesn't return an error, which it should do if no data is received (eg, if it times out).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top