I have a problem with MailSlots in windows (C/C++).
I am trying to make two simple programs right now, but the communication is not good at the last step.
This is my int main from the server.cpp
int main()
{
HANDLE ss, sc, sc2r;
LPCTSTR errMsg;
ss = CreateMailslot("\\\\.\\mailslot\\ss", 0, MAILSLOT_WAIT_FOREVER, NULL);
if (ss == INVALID_HANDLE_VALUE)
{
printf("Invalid ss value");
return -1;
}
for (;;)
{
DWORD msgSize;
DWORD nr;
BOOL err;
/* Get the size of the next record */
err = GetMailslotInfo(ss, 0, &msgSize, 0, 0);
char x[100];
char nrr[10];
if (msgSize != (DWORD)MAILSLOT_NO_MESSAGE)
{
DWORD numRead;
/* Read the record */
err = ReadFile(ss, x, msgSize, &numRead, 0);
int wrds=count(x)+1;
sc = CreateFile("\\\\*\\mailslot\\sc", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
itoa(wrds,nrr,10);
err = WriteFile(sc, nrr, sizeof(nrr), &nr, 0);
//cout<<err<<endl;
//cout<<x;
//cout<<err;
strrev(x);
err=WriteFile(sc, x, sizeof(x), &nr, 0);
}
}
return(0);
}
Here is the client source:
int main()
{
HANDLE ss, sc, sc2;
LPCTSTR errMsg;
BOOL err;
DWORD numWritten;
sc = CreateMailslot("\\\\.\\mailslot\\sc", 0, MAILSLOT_WAIT_FOREVER, NULL);
ss = CreateFile("\\\\*\\mailslot\\ss", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (ss == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed. ");
// Close any mailslot we opened
if (ss != INVALID_HANDLE_VALUE) CloseHandle(ss);
return -1;
}
char x[100];
char z[100];
printf("Write the damn sentence:");
cin.getline(x,100);
err = WriteFile(ss, x, sizeof(x), &numWritten, 0);
if (!err) printf("WriteFile failed. ");
DWORD rd;
ReadFile(sc,x,sizeof(x),&rd,NULL);
cout<<x<<endl;
ReadFile(sc,z,sizeof(z),&rd,NULL);
cout<<z;
return 0;
}
It seems like the server is sending the same thing three times. I tested the client in debugger and he gets it right, but can’t figure it out why the server is sending three times the same thing.
Do you have any suggestions ?
You are confusing
sizeofwithstrlen. Callingsizeof(nrr)will always return 10. The server program will do a single write of 10 bytes, even if the buffer only contains 2 valid bytes.Replace
sizeofwith1+strlento fix the problem.For example, in server.cpp if
wrdsis 1, thennrrwill be{ 0x31, 0x00 }in memory. What looks like a repeated write is really a single write of uninitialzed memory.strlenwill give you the count of valid characters, +1 for the terminating null.It might be a good idea to initialize nrr, with
*nrr = 0first. You can test thatitoasucceeeded withif(*nrr)and handle the failure as you see fit.Oh, and one more thing : you are leaking handles. It might not matter much in the client, but server leaks a handle to a mailslot at every iteration. You should reuse the mailslot handle or close it at every iteration.