- Home /
simple namedpipe code not working as expected
Hi, I'm trying to get familiar with named pipes in Unity. To get started I ave a simple test program where the server sends '1' to the client, and the client sends '2' to the server. I got the program running for two console application. Now I want Unity to communicate with my console application. I have the following code. The console application:
using System;
using System.Text;
using System.IO.Pipes;
namespace PipeSample
{
class Program
{
static void Main(string[] args)
{
using (NamedPipeServerStream namedPipeServer = new NamedPipeServerStream("test_pipe",PipeDirection.InOut))
{
Console.WriteLine("Waiting for connection on named pipe");
namedPipeServer.WaitForConnection();
namedPipeServer.WriteByte(1);
int byteFromClient = namedPipeServer.ReadByte();
Console.WriteLine(byteFromClient);
}
Console.ReadLine();
}
}
}
Unity Code:
using UnityEngine;
using System.Collections;
using System.IO.Pipes;
public class PipeWork : MonoBehaviour
{
void ReceiveByteAndRespond()
{
using (NamedPipeClientStream clientStream = new NamedPipeClientStream("test_pipe"))
{
clientStream.Connect();
Debug.Log(clientStream.ReadByte());
clientStream.WriteByte(2);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
ReceiveByteAndRespond();
}
}
}
So when I run the code and press space, in the Unity console I see '1' as expected. Unfortunately in the console application I see '1' too after some delay. Can somebody explain to me why this happens?
Answer by LK84 · Dec 30, 2016 at 01:32 PM
Ok, found a solution. For the console application:
using System;
using System.Text;
using System.IO.Pipes;
namespace PipeSample
{
class Program
{
static void Main(string[] args)
{
using (NamedPipeServerStream namedPipeServer = new NamedPipeServerStream("test_pipe",PipeDirection.InOut,1,PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
Console.WriteLine("Waiting for connection on named pipe");
namedPipeServer.WaitForConnection();
namedPipeServer.WriteByte(1);
Console.WriteLine(namedPipeServer.ReadByte());
}
Console.ReadLine();
}
}
}
For the Unity Code:
using UnityEngine;
using System.Collections;
using System.IO.Pipes;
using System.Threading;
public class NamedPipeClient : MonoBehaviour
{
Thread secondThread;
byte[] messageBytes;
string messageTo;
private AutoResetEvent sendEvent;
void Start()
{
sendEvent = new AutoResetEvent(false);
}
void ReceiveByteAndRespond()
{
using (NamedPipeClientStream clientStream = new NamedPipeClientStream(".","test_pipe",PipeDirection.InOut))
{
clientStream.Connect();
Debug.Log(clientStream.ReadByte());
clientStream.Flush();
sendEvent.WaitOne();
clientStream.WriteByte(2);
clientStream.WaitForPipeDrain();
}
secondThread.Abort();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if(secondThread!=null && secondThread.IsAlive)
{
Debug.Log("Thread already running");
return;
}
secondThread = new Thread(ReceiveByteAndRespond);
secondThread.Start();
}
if (Input.GetKeyDown(KeyCode.KeypadEnter))
{
Debug.Log("Send");
sendEvent.Set();
}
}
public void OnApplicationQuit()
{
if (secondThread != null)
{
if (secondThread.ThreadState != ThreadState.Aborted)
secondThread.Abort();
}
}
}
The main difference is that I added a second thread which does all the namedpipe related stuff. Also for further reference, I had an old namedpipe still running on my pc which messed up things. You might wanna check through https://technet.microsoft.com/en-us/sysinternals/bb896653.aspx "Find -> Find Handle or DLL..." option and enter the pattern "\Device\NamedPipe\"