2

I am using Namedpipes communication(C++) to transfer data between two processes. For the sake of comfort, I am using wstring to transfer the data and everything is fine at the transfer end. I am not able to receive the total data on the receiving end. The following is the transfer end code.

wstringstream send_data;        
send_data << "10" << " " << "20" << " " << "30" << " " << "40" << " " << "50" << " " << "60" << "\0" ;
DWORD numBytesWritten = 0;
result = WriteFile(
    pipe, // handle to our outbound pipe
    send_data.str().c_str(), // data to send
    send_data.str().size(), // length of data to send (bytes)
    &numBytesWritten, // will store actual amount of data sent
    NULL // not using overlapped IO
);

The following is the receiving end code.

wchar_t buffer[128];
DWORD numBytesRead = 0;
BOOL result = ReadFile(
    pipe,
    buffer, // the data from the pipe will be put here
    127 * sizeof(wchar_t), // number of bytes allocated
    &numBytesRead, // this will store number of bytes actually read
    NULL // not using overlapped IO
);

if (result) {
    buffer[numBytesRead / sizeof(wchar_t)] = '\0'; // null terminate the string
    wcout << "Number of bytes read: " << numBytesRead << endl;
    wcout << "Message: " << buffer << endl;

}

The result in buffer contains only 10 20 30 Can someone please explain me why the data is truncated.

  • 1
    Are you sure the data is truncated? You don't appear to check the pipe to see if there is anything remaining, waiting to be read. You also don't appear to check to see if you wrote as many bytes as you think you wrote. –  Jun 29 '15 at 20:10
  • Having a read from some stream, you should not expect a certain size you get (it might be less or even zero). React on some error or eof condition –  Jun 29 '15 at 20:13
  • 2
    Shouldn't `send_data.str().size()` be `send_data.str().size() * sizeof(wchar_t) / sizeof(char)` since you are sending multibyte characters? – NathanOliver Jun 29 '15 at 20:15
  • @Hurkyl: Yes, I did check on before I transfer, What the data in wstringstream contains. All the data appeared to be present. If, I am not wrong "buffer" is supposed to print all the data the pipe contains. – user3043517 Jun 29 '15 at 20:18
  • @NathanOliver: Wow! nice one.. Now, I get the whole data. Thanks a Lot – user3043517 Jun 29 '15 at 20:21
  • @user3043517: I'm not concerned with before or after the transfer: I'm concerned with the transfer itself. Don't get the wrong idea that `WriteFile` will transfer everything you asked it to and that `ReadFile` will return exactly the contents that were written by a `WriteFile` call (unless you've carefully checked the documentation to be sure). Many communication channels simply don't work that way at all, and from the arguments to your functions, it looks like this channel is one of those that don't. –  Jun 29 '15 at 20:49

1 Answers1

0

You are not sending all of the data with the WriteFile() function. You are sending send_data.str().size() number of bytes which is incorrect as size() gives you the number of characters and not the number of bytes. You can change your code to use:

send_data.str().size() * sizeof(wchar_t) / sizeof(char)

Which will send the correct amount of bytes.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • `/ sizeof(char)` is redundant and useless, as `sizeof(char)` is always 1 per the C++ standard, even if `char` is not 8 bits on every platform (see `CHAR_BIT`). But on Windows, `char` is 8 bits. – Remy Lebeau Jun 29 '15 at 22:09
  • Also, `send_data.str()` returns a new `std::wstring` every time it is called. The sending code should save the result of `send_data.str()` to a local `std::wstring` variable first, then call `c_str()` and `size()` on that variable. – Remy Lebeau Jun 29 '15 at 22:12
  • @RemyLebeau I realize `sizeof(char)` will always be 1 but it helps to visualize that you are doing a ration to the size of the characters. Since `sizeof()` is evaluated at compile time the code at runtime should just be multiplied against a constant. – NathanOliver Jun 30 '15 at 11:54