tags:

views:

168

answers:

0

I have a server named pipe that establishes named pipes in an overlapped mode. This server instance waits for clients which send binary files into this pipe. The server reads this data using ReadFile() native method (the application is written in C# but I am using Win32 native methods). The funny thing is: when I run this program in the debug mode, all works fine, but when I execute the .exe file outside the IDE, it doesn't get the first set of bytes read. Since the client is sending a binary file, it is normally bigger than the size of the buffer that the server reads, so the server instance will need to call the ReadFile() more than once. In these calls, the first is always missing or ignored or...!!

    /// <summary>
    /// The method determines which operation to do next - read or write. It returns false if failed to. 
    /// </summary>
    /// <remarks>Here is the C++ example it was adopted from: 
    /// http://msdn.microsoft.com/en-us/library/aa365603(VS.85).aspx
    /// </remarks>
    private bool selectOperation(Int32 i)
    {
        bool fSuccess = false;
        UInt32 dwErr;
        uint cbRet = 0;

        switch (mPipeServer[i].Pipe.dwState)
        {
            // READING_STATE: 
            // The pipe instance is connected to the client 
            // and is ready to read a request from the client.
            case READING_STATE:
                Debug.WriteLine("Descriptor 2: " + mPipeServer[i].Pipe.hPipeInst.ToString());

                fSuccess = NativeMethods.ReadFile(
                    mPipeServer[i].Pipe.hPipeInst,
                    mPipeServer[i].Pipe.chRequest,
                    mSize,
                    out mPipeServer[i].Pipe.cbRead,
                    mPipeServer[i].Pipe.OverlappedPtr);

                // The read operation completed successfully (number of bytes read >0)
                if (fSuccess && mPipeServer[i].Pipe.cbRead != 0)
                {
                    //If we got here ReadFile managed to read all data within its call
                    mPipeServer[i].Pipe.fPendingIO = false;
                    byte[] data = new byte[mPipeServer[i].Pipe.cbRead];

                    mPipeServer[i].Pipe.dwState = READING_STATE;// keep READ_MODE as the server is only to read data
                    Marshal.Copy(mPipeServer[i].Pipe.chRequest, data, 0, data.Length);
                    //did here some testing as to what data we get after  executing the ReadFile(). when we run in Debug mode, we get the beginning of the file is was sent by the client. But if it's run outside the Visual Studio IDE, the first set of bytes which have been read will be the SECOND set and not the first actual set!
 //I did something stupid like if(this.round==1) 
 //round is just a variable initialized to 1 and then incremented every time we visit the REadFile()
MessageBox.Show(Encoding.ASCII(data)); //I am sending ASCII data as binary, shouldn't be a problem. And now I am displaying them in a Message Box

                    NamedPipeManager.round++;

                    return true;
                }
                // The read operation is still pending. 
                dwErr = NativeMethods.GetLastError();

                if (!fSuccess && (dwErr == NamedPipeServer.ERROR_IO_PENDING))
                {


                    mPipeServer[i].Pipe.fPendingIO = true;
                    return true;
                }

                DebugWin32Exception("selectOperation - READING_STATE");

                // An error occurred; disconnect from the client. 
                return false;


                }

                // An error occurred; disconnect from the client. 
                return false;

            default:
                ThrowWin32Exception("selectOperation - Ivalid Pipe State");
                break;

        }

        return true;
    }

I tried many things to check what's wrong, but nothing seems to be clear for me! Can anyone help with this!

Thanks.

related questions