C#
// Open the named pipe. var server = new NamedPipeServerStream("NPtest"); Console.WriteLine("Waiting for connection..."); server.WaitForConnection(); Console.WriteLine("Connected."); var br = new BinaryReader(server); var bw = new BinaryWriter(server); while (true) { try { var len = (int) br.ReadUInt32(); // Read string length var str = new string(br.ReadChars(len)); // Read string Console.WriteLine("Read: \"{0}\"", str); str = new string(str.Reverse().ToArray()); // Just for fun var buf = Encoding.ASCII.GetBytes(str); // Get ASCII byte array bw.Write((uint) buf.Length); // Write string length bw.Write(buf); // Write string Console.WriteLine("Wrote: \"{0}\"", str); } catch (EndOfStreamException) { break; // When client disconnects } } Console.WriteLine("Client disconnected."); server.Close(); server.Dispose();
Python
In this example, I implement a very simple protocol, where every "message" is a 4-byte integer (import time import struct f = open(r'\\.\pipe\NPtest', 'r+b', 0) i = 1 while True: s = 'Message[{0}]'.format(i) i += 1 f.write(struct.pack('I', len(s)) + s) # Write str length and str f.seek(0) # EDIT: This is also necessary print 'Wrote:', s n = struct.unpack('I', f.read(4))[0] # Read str length s = f.read(n) # Read str f.seek(0) # Important!!! print 'Read:', s time.sleep(2)
UInt32
in C#, 'I'
(un)pack format in Python), which indicates the length of the string that follows. The string is ASCII.
Important things to note here:
- Python
- The third parameter to
open()
means "unbuffered". Otherwise, it will default to line-buffered, which means it will wait for a newline character before actually sending it through the pipe. - I'm not sure why, but omitting the
seek(0)
will cause an IOError #0. I was clued to this by a StackOverflow question.
References:
- .NET
NamedPipeServerStream
class on MSDN - Python
open()
method on Python.org