Named Pipes (slow?) menu

User Tag List

Results 1 to 10 of 10
  1. #1
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Named Pipes (slow?)

    Heya guys,

    I'm currently using named pipes to communicate from my C# (main) application with my injected C++ library.

    I did some performance monitoring, and recognized that the named pipe connection is really "slow".

    Sending commands to the library takes about 2ms, that's okay (but could be better).

    BUT receiving data takes really long.
    Sending a request to the C++ pipe server and getting the return value in C# takes nearly 20 to 25ms.

    Is this normal? (I'm using Async NamedPipe to read/receive commands in C#)

    Is there another / better / faster way to communicate with the library?
    (I don't want to write my Core in C++)

    Named Pipes (slow?)
  2. #2
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could use a shared memory section, but in theory local named pipes should be almost as fast (and way less complicated to write). At least, that's what MSDN claims...
    Don't believe everything you think.

  3. #3
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the fast repsonse.
    At first I was using shared memory, but screwed that because I wanted to use muplitple instaces of my program.

    Yeah I thought named pipes are really fast, maybe is my code ****ed up.
    Or? 20ms aren't normal for getting a response?

  4. #4
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by jockel View Post
    Thanks for the fast repsonse.
    At first I was using shared memory, but screwed that because I wanted to use muplitple instaces of my program.

    Yeah I thought named pipes are really fast, maybe is my code ****ed up.
    Or? 20ms aren't normal for getting a response?
    Unless your system is under an insane amount of load, 20ms for a NP response seems very long to me.

    But I have to say that I've never benchmarked it (especially when you try doing the Async methods, which might introduce additional delays). Is it possible for you to reduce your complexity temporarily in order to run a few tests? If so, I'd like to see the results of an asynchronous vs. synchronous shootout.
    Don't believe everything you think.

  5. #5
    Shynd's Avatar Contributor
    Reputation
    97
    Join Date
    May 2008
    Posts
    393
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try using it synchronously by importing CreateNamedPipe into your C# application and writing to it as you would a normal file.

    Code:
    const int PIPE_ACCESS_DUPLEX = 0x00000003;
    const int PIPE_ACCESS_INBOUND = 0x00000001;
    const int PIPE_ACCESS_OUTBOUND = 0x00000002;
    const int FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
    const int PIPE_TYPE_BYTE = 0x00000000;
    const int PIPE_TYPE_MESSAGE = 0x00000004;
    const int PIPE_READMODE_BYTE = 0x00000000;
    const int PIPE_READMODE_MESSAGE = 0x00000002;
    const int PIPE_WAIT = 0x00000000;
    const int PIPE_NOWAIT = 0x00000001;
    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x40000000;
    const int OPEN_EXISTING = 0x00000003;
    
    
    [DllImport("kernel32.dll")]
    extern static SafeFileHandle CreateNamedPipe(string name, uint openMode, uint pipeMode,
    	uint maxInstances, uint outBufferSize, uint inBufferSize, uint defaultTimeOut,
    	IntPtr securityAttributes);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    extern static Int32 ConnectNamedPipe(SafeFileHandle namedPipe, IntPtr overlapped);
    
    string pipename = "\\\\.\\pipe\\mypipe"
    SafeFileHandle NamedPipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 10, 1000, 1000, 500, IntPtr.Zero);
    FileStream pipe = new FileStream(NamedPipe, FileAccess.ReadWrite);
    
    for (byte[] pipeBytes = new byte[255]; pipe.CanRead; pipeBytes = new byte[255];)
    {
    	pipe.Read(pipeBytes, 0, pipeBytes.Length);
    	pipe.Write(new byte[] { 0xFF, 0xFF }, 0, 2);
    
    	str = new StringBuilder();
    
    	//print out information
    	for (int i = 0; i < pipeBytes.Length; i++)
    		if (pipeBytes[i] != '/0')
    			str.Append(Convert.ToChar(pipeBytes[i]));
    			
    	Console.WriteLine("Len: " + str.Length + " -- " + str.ToString());
    }

  6. #6
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Shynd View Post
    Try using it synchronously by importing CreateNamedPipe into your C# application and writing to it as you would a normal file.

    Code:
    const int PIPE_ACCESS_DUPLEX = 0x00000003;
    const int PIPE_ACCESS_INBOUND = 0x00000001;
    const int PIPE_ACCESS_OUTBOUND = 0x00000002;
    const int FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
    const int PIPE_TYPE_BYTE = 0x00000000;
    const int PIPE_TYPE_MESSAGE = 0x00000004;
    const int PIPE_READMODE_BYTE = 0x00000000;
    const int PIPE_READMODE_MESSAGE = 0x00000002;
    const int PIPE_WAIT = 0x00000000;
    const int PIPE_NOWAIT = 0x00000001;
    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x40000000;
    const int OPEN_EXISTING = 0x00000003;
    
    
    [DllImport("kernel32.dll")]
    extern static SafeFileHandle CreateNamedPipe(string name, uint openMode, uint pipeMode,
    	uint maxInstances, uint outBufferSize, uint inBufferSize, uint defaultTimeOut,
    	IntPtr securityAttributes);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    extern static Int32 ConnectNamedPipe(SafeFileHandle namedPipe, IntPtr overlapped);
    
    string pipename = "\\\\.\\pipe\\mypipe"
    SafeFileHandle NamedPipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 10, 1000, 1000, 500, IntPtr.Zero);
    FileStream pipe = new FileStream(NamedPipe, FileAccess.ReadWrite);
    
    for (byte[] pipeBytes = new byte[255]; pipe.CanRead; pipeBytes = new byte[255];)
    {
    	pipe.Read(pipeBytes, 0, pipeBytes.Length);
    	pipe.Write(new byte[] { 0xFF, 0xFF }, 0, 2);
    
    	str = new StringBuilder();
    
    	//print out information
    	for (int i = 0; i < pipeBytes.Length; i++)
    		if (pipeBytes[i] != '/0')
    			str.Append(Convert.ToChar(pipeBytes[i]));
    			
    	Console.WriteLine("Len: " + str.Length + " -- " + str.ToString());
    }
    Shynd, you REALLY like your PInvokes don't ya?

    IpcChannel Class (System.Runtime.Remoting.Channels.Ipc)

    IPC channels are fully wrapped via .NET. (Just reference System.Runtime.Remoting) There's plenty of things in there to handle whatever you need.

  7. #7
    Shynd's Avatar Contributor
    Reputation
    97
    Join Date
    May 2008
    Posts
    393
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That was from a program I wrote back in .NET 1.1. I haven't used NamedPipes since then.

    Anyway, the reason I said to start troubleshooting from there is he mentioned he's using the recently (2.0? I haven't paid attention, to be honest) added asynchronous named pipes methods and getting shitty results. I have no idea if there's some sort of overhead or if his problem is with the way in which he's implementing his named pipe (either in his managed application or unmanaged injected library), and this would be a good way to make sure that the possibility of unknown overhead from the managed methods is not the culprit, thus narrowing down his issue.

    The method I provided is simple, and I really didn't feel like looking into the new IPC crap they added since the last time I used it.

  8. #8
    BoogieManTM's Avatar Active Member
    Reputation
    52
    Join Date
    May 2008
    Posts
    193
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by jockel View Post
    Thanks for the fast repsonse.
    At first I was using shared memory, but screwed that because I wanted to use muplitple instaces of my program.

    Yeah I thought named pipes are really fast, maybe is my code ****ed up.
    Or? 20ms aren't normal for getting a response?
    Sounds like you're not flushing the buffer when writing to the pipe in the C++ code. Set the buffer to autoflush and you should be good.

  9. #9
    ostapus's Avatar Active Member
    Reputation
    60
    Join Date
    Nov 2008
    Posts
    180
    Thanks G/R
    3/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    in .net 3+ NamedPipes is in System.Core.NamedPipes. not sure though how it is implemented nor did any benchmarking. just my 2c. and yes, dont forget to flush.

  10. #10
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hum thanks for your responses.

    Server and Client pipe are now in sync mode


    Thats what my C++ library sendmessage looks like (Pseudo Code)

    Code:
    WriteFile(handle, bytes);
    FlushFileBuffers(handle);

    I'm using the 3+ Framework with System.IO.Pipes in C#.

    What I do to get a response from the C++ Library in C# is the following (Pseudo):


    Code:
    NamedPipeClient.Write(bytes);
    NamedPipeClient.Flush();
    NamedPipeClient.Read(readByteArray);
    Thats what my profiler says:


    Writing to the pipe is really performant
    Code:
     Write - 1,2519 ms - 25 calls - System.IO.Pipes.PipeStream.Write
      Flush - 0,0073 ms - 25 calls - System.IO.Pipes.PipeStream.Flush()

    But reading really sucks looking at the time:

    Code:
    Read - 415,06 ms - 16 calls - System.IO.Pipes.PipeStream.Read(Byte [], Int32, Int32)

    16 Calls to Read takes in total 415ms.

    Thats 25ms per read request, am I doing something wrong, can someone confirm that pipes are that slow?

Similar Threads

  1. Named Pipes C++
    By drognir in forum WoW Memory Editing
    Replies: 3
    Last Post: 07-28-2009, 06:16 PM
  2. Named Pipes?
    By xzidez in forum WoW Memory Editing
    Replies: 3
    Last Post: 05-14-2009, 05:41 PM
  3. [Exploit] Name Change
    By Ced in forum World of Warcraft Exploits
    Replies: 22
    Last Post: 09-02-2006, 03:00 AM
  4. Buying Colour in your name
    By Cush in forum Community Chat
    Replies: 8
    Last Post: 07-08-2006, 10:58 PM
  5. Name Change Exploit
    By Matt in forum World of Warcraft Exploits
    Replies: 3
    Last Post: 05-16-2006, 12:50 PM
All times are GMT -5. The time now is 03:43 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search