named pipe client won't work in unity3d

拜拜、爱过 提交于 2019-12-12 09:51:37

问题


I wrote this C# code to have namedPipeServer and NamedPipeClient, with Asynchronous read and write settings, connect to each other. Both code runs perfectly on visual studio 2010 that I am using with read and write working well without any application freeze during runtime.

But I want the client side running in unity3d. The problem I encounter is in client side code implemented in Unity3D. When I use Write_to_Server_Async(string message), read in the server side is not invoked and is only invoked when I quit Unity3d (I have end its process typically). I can tell something wrong with Unity3D, because the exact code works perfectly in visual studio, so I know my code is implemented the right way. I have heard about how unity3d does not really use real threads unless user manually creates one but even that has not solved the problem. My speculation is Unity3D developers might have created their version of .NET library 3.5 (sounds bizzare (does explain why they still haven't adopted 4.5)) or somehow they must have structured their library in a way that by default functions like NamedPipeClientStream.BeginWrite cannot create its own real thread. But then again I am not sure if its the problem with threads.

At the moment, I would like anyone to come up with good explanation.

Make sure to replace Debug.WriteLine to UnityEngine.Debug.Log in unity3d.

Below is Client Main method code and class

class PipeClient 
{
    private static Asynchronus_NamedPipe_Client client;


    static void Main(string[] args)
    {
       client = new Asynchronus_NamedPipe_Client("mypipe7055");
       while (client.Is_connected_to_server()) {
           if (Console.ReadKey().Key == ConsoleKey.T)
           {
               client.Write_to_Server_Async("NEX CLIENT");

           }
       }
    }
}

Asynchronus_NamedPipe_Client class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Security.Principal;
using System.Diagnostics;
using System.Threading;

namespace NamedPipes_CLIENT
{

public class Asynchronus_NamedPipe_Client
{


    public readonly string pipe_address;
    private System.IO.Pipes.NamedPipeClientStream clientStream;

    public bool filter_message = true;



    private string Server_Message = null;




    public event ASYNC_pipe_status_callback ASYNC_external_Write_Completed;
    public event ASYNC_pipe_status_callback ASYNC_external_Read_Completed;
    public delegate void ASYNC_pipe_status_callback(string message);


    private byte[] read_buffer = new byte[1024];
    private byte[] write_buffer = new byte[1024];

    private IAsyncResult read_result;
    private IAsyncResult write_result;

    private int read_id = 1;

    public Asynchronus_NamedPipe_Client(string pipe_address)
    {
        try
        {
            this.pipe_address = pipe_address;
            //  if(clientStream.IsConnected){UnityEngine.Debug.Log("Server Already Running");}else{}
            clientStream = new NamedPipeClientStream(".", this.pipe_address, PipeDirection.InOut, PipeOptions.Asynchronous);


            clientStream.Connect(1);
            if (clientStream.IsConnected)
            {
                Console.WriteLine("Connected to Server");
                Read_from_Server_Async();
            }
            else { Console.WriteLine("Could NOT connect to Server"); }

        }
        catch (Exception oEX) { Console.WriteLine("Application Pipe Error: "+oEX.Message); }


    }



    public void Write_to_Server_Async(string message)
    {
        if (clientStream != null)
        {
            if (clientStream.CanWrite && clientStream.IsConnected)
            {

                clientStream.WaitForPipeDrain();
                ASCIIEncoding.ASCII.GetBytes(message).CopyTo(write_buffer,0);
                clientStream.BeginWrite(write_buffer, 0, write_buffer.Length, new AsyncCallback(Async_Write_Completed), 1);

            } else { close_pipe(); }
        }

    }



    public void Read_from_Server_Async()
    {
        if (clientStream.CanRead && clientStream.IsConnected)
        {
            clientStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(Async_Read_Completed), 2);
        } else { close_pipe(); }

    }



    private void Async_Write_Completed(IAsyncResult result)
    {
        clientStream.EndWrite(result);
        Debug.WriteLine("Written To Server => " + ASCIIEncoding.ASCII.GetString(write_buffer));
     // close_pipe();
    }



    private void Async_Read_Completed(IAsyncResult result)
    {

        clientStream.EndRead(result);
        Server_Message = ASCIIEncoding.ASCII.GetString(read_buffer);
        this.Server_Message.Trim();
        Console.WriteLine("Received from Server => " + Server_Message);
        Debug.WriteLine("Received from Server => " + Server_Message);
          if (clientStream.CanRead && clientStream.IsConnected)
        {
        Read_from_Server_Async();
        }
          else { close_pipe(); }

    }

    public Boolean Is_connected_to_server() {
        return clientStream.IsConnected;
    }



    public void close_pipe()
    {
        if (clientStream != null)
        {
            if (clientStream.IsConnected)
            {
                clientStream.Close();
                clientStream.Dispose();

                Debug.WriteLine(" Pipe Closed");
            }
        }

    }
}

}

Server side Main method implementation

    static void Main(string[] args)
    {


       Asynchronus_NamedPipe_Server Async_server = new Asynchronus_NamedPipe_Server("mypipe7055");

        while (true)
            {

              do
              {
                  Async_server.Write_to_Client_Async("yeye");
                  Console.WriteLine("escape key");

              } while (Console.ReadKey(true).Key != ConsoleKey.Escape);

            }

    }

Server Side Class -----

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.ComponentModel;
using System.Diagnostics;


namespace Application_Pipe
{
public class Asynchronus_NamedPipe_Server
{
    public readonly string pipe_address;
    private System.IO.Pipes.NamedPipeServerStream namedPipeServerStream;
    private string Server_Message;



    public delegate void ASYNC_pipe_status_callback(string message);


    private byte[] read_buffer = new byte[1024];
    private byte[] write_buffer = new byte[1024];


    public Asynchronus_NamedPipe_Server(string pipe_address)
    {
        try
        {

            this.pipe_address = pipe_address;
            namedPipeServerStream = new NamedPipeServerStream(this.pipe_address,
                 PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); //new NamedPipeServerStream(pipe_address);
            Console.WriteLine("Connecting to Client...");
            namedPipeServerStream.WaitForConnection();
            Console.WriteLine("Connected to Client");
           Read_from_Client_Async();

        }
        catch (Exception oEX) { Console.WriteLine(oEX.Message); }
    }





    public void Write_to_Client_Async(string message)
    {
        if (namedPipeServerStream != null)
        {
            if (namedPipeServerStream.CanWrite && namedPipeServerStream.IsConnected)
            {
                namedPipeServerStream.WaitForPipeDrain();
                ASCIIEncoding.ASCII.GetBytes(message).CopyTo(write_buffer,0);

                namedPipeServerStream.BeginWrite(write_buffer, 0, write_buffer.Length, new AsyncCallback(Async_Write_Completed), 2);

            }
            else { close_pipe(); }
        }
    }



    public void Read_from_Client_Async()
    {

        if (namedPipeServerStream != null)
        {
            if (namedPipeServerStream.CanRead && namedPipeServerStream.IsConnected)
            {

                namedPipeServerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(Async_Read_Completed), 1);
            } else { close_pipe(); }

        }
    }



    private void Async_Read_Completed(IAsyncResult result)
    {



       namedPipeServerStream.EndRead(result);

        this.Server_Message = ASCIIEncoding.ASCII.GetString(read_buffer);
        this.Server_Message.Trim();
        Debug.WriteLine("Received from Client => " + this.Server_Message+" <=REnd");

       Read_from_Client_Async();

    }


    private void Async_Write_Completed(IAsyncResult result)
    {
        namedPipeServerStream.EndWrite(result);
        Debug.WriteLine("Written To Client => " + ASCIIEncoding.ASCII.GetString(write_buffer));


    }

    public Boolean Is_connected_to_server()
    {
        return this.namedPipeServerStream.IsConnected;
    }


    public void close_pipe()
    {
        if(namedPipeServerStream.IsConnected){
        namedPipeServerStream.Disconnect();
        }
        namedPipeServerStream.Close();
        namedPipeServerStream.Dispose();

        Debug.WriteLine(" Pipe Closed");
    }

} //------class End
}

来源:https://stackoverflow.com/questions/27582846/named-pipe-client-wont-work-in-unity3d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!