双向C ++到C#通信使用命名管道 [英] Two way C++ to C# communication using named pipes

查看:706
本文介绍了双向C ++到C#通信使用命名管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个VC ++ 6的应用程序和一个C#应用程序之间的双向通信。我使用命名管道。在我的C ++代码,我可以阅读从C#客户端的消息,但随后的服务器死,我不得不再次重新启动它。



我想要做的是有C#应用程序连接到C ++应用程序,请求状态,和C ++应用程序熄灭,检查状态,然后返回要么忙或闲。



我不能,因为它说的连接已关闭写东西回C#的客户端。有些事情我都注释掉件事情我已经试过了。



C ++代码(开始作为一个线程)

  UINT CNamedPipe :: StartNamedPipeServer()
{
LPTSTR lpszPipename =\\\\.\\pipe\\SAPipe ;
HANDLE hPipe;
BOOL FLG;
DWORD dwWrite,dwRead;
焦炭szServerUpdate [200];
焦炭szClientUpdate [200];

hPipe = CreateNamedPipe时(lpszPipename,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |
PIPE_READMODE_MESSAGE |
PIPE_NOWAIT,//将NOWAIT
PIPE_UNLIMITED_INSTANCES改变,/ / MAX实例
BUFSIZE,//输出缓冲区大小
BUFSIZE,//输入缓冲区的大小
PIPE_TIMEOUT,//客户端超时
NULL)。 //没有安全属性

如果(hPipe == INVALID_HANDLE_VALUE)
返回0;

ConnectNamedPipe(hPipe,NULL);

,而(m_bServerActive)//这似乎很好地工作......
{

//读取从客户
FLG = ReadFile的(hPipe ,szClientUpdate,strlen的(szClientUpdate),放大器; dwRead,NULL);

如果(FLG)//读取来自客户端的东西!!!!
{
CString的csMsg,csTmp;

的for(int i = 0; I< dwRead;我++){
csTmp.Format(%C,szClientUpdate [I]);
csMsg + = csTmp;
}


AfxMessageBox的(客户端消息:+ csMsg);

的strcpy(szServerUpdate,忙);

//将状态给客户
FLG = WriteFile的(hPipe,szServerUpdate,strlen的(szServerUpdate),放大器; dwWrite,NULL);

EndServer();
startserver的();
}

}

返回0;



}



C#代码:

 公共无效ThreadStartClient(obj对象)
{
//确保我们只在服务器启动后,客户端创建管道
ManualResetEvent的SyncClientServer =(ManualResetEvent的)目标文件;

//只有不断后服务器创建 - 否则我们就无法运行的
// SyncClientServer.WaitOne();使用

(NamedPipeClientStream pipeStream =新NamedPipeClientStream(。,SAPipe))
{
// connect函数将无限期地等待管道变得可用
//如果这是不能接受的指定最长等待时间(毫秒)
pipeStream.Connect();

//利用客户端写入服务器
(StreamWriter的SW =新的StreamWriter(pipeStream))
{
sw.WriteLine(你叫什么状态?) ;
}

//读取服务器响应
/ *使用(StreamReader的SR =新的StreamReader(pipeStream))
{
字符串TEMP =;
TEMP = sr.ReadLine(); //管道已经关闭在这里...为什么?

MessageBox.Show(TEMP);

} * /

//pipeStream.Close();

}
}
}


解决方案

的处置一个的StreamWriter 的StreamReader 将关闭底层流。



您使用的语句,因此会导致流关闭。

 公共无效ThreadStartClient (obj对象)
{
//确保服务器已经创建的管道
ManualResetEvent的SyncClientServer =(ManualResetEvent的)目标文件后,我们才开始客户端;

//只有不断后服务器创建 - 否则我们就无法运行的
// SyncClientServer.WaitOne();使用

(NamedPipeClientStream pipeStream =新NamedPipeClientStream(。,SAPipe))
{
// connect函数将无限期地等待管道变得可用
//如果这是不能接受的指定最长等待时间(毫秒)
pipeStream.Connect();


//从客户端写入服务器
的StreamWriter SW =新的StreamWriter(pipeStream))
sw.WriteLine(你叫什么状态?);

//读取服务器响应
StreamReader的SR =新的StreamReader(pipeStream)
字符串TEMP =;
TEMP = sr.ReadLine(); //管道已经关闭在这里...为什么?

MessageBox.Show(TEMP);
}
}



还应当指出的是,因为你包装你的流在using语句,注释掉 pipeStream.Close()不需要功能。


I am trying to have a 2-way communication between a VC++ 6 app and a C# app. I am using named pipes. In my C++ code I can read the message from the C# client but then the server "dies" and I have to restart it again.

What I want to do is have the C# app connect to the C++ app, request a status, and the C++ app goes off and checks the status, and then returns either "busy" or "idle".

I can't write anything back to the C# client as it says the connection has been closed. Some things I have commented out are things I have tried already.

C++ code (started as a thread)

UINT CNamedPipe::StartNamedPipeServer()
{
LPTSTR lpszPipename = "\\\\.\\pipe\\SAPipe"; 
    HANDLE hPipe; 
    BOOL flg;
    DWORD dwWrite,dwRead;
    char szServerUpdate[200];
    char szClientUpdate[200];

    hPipe = CreateNamedPipe (    lpszPipename, 
                                PIPE_ACCESS_DUPLEX,
                                PIPE_TYPE_MESSAGE | 
                                PIPE_READMODE_MESSAGE | 
                                PIPE_NOWAIT,                    //changed from nowait
                                PIPE_UNLIMITED_INSTANCES,    // max. instances 
                                BUFSIZE,                    // output buffer size 
                                BUFSIZE,                    // input buffer size 
                                PIPE_TIMEOUT,                // client time-out 
                                NULL);                        // no security attribute 

    if (hPipe == INVALID_HANDLE_VALUE) 
        return 0;

    ConnectNamedPipe(hPipe, NULL);

    while(m_bServerActive)  //This seems to work well ....
    {

        //Read from client
        flg = ReadFile(hPipe,szClientUpdate,strlen(szClientUpdate),&dwRead, NULL);

        if(flg) //Read something from the client!!!!
        {
            CString csMsg,csTmp;

            for(int i=0;i<dwRead;i++){
                csTmp.Format("%c",szClientUpdate[i]);
                csMsg += csTmp;
            }


            AfxMessageBox("Client message: " + csMsg);

            strcpy( szServerUpdate,"busy");

            //Write status to Client
            flg = WriteFile(hPipe, szServerUpdate, strlen(szServerUpdate), &dwWrite, NULL);

            EndServer();
            StartServer();
        }

    }

    return 0;

}

C# Code:

public void ThreadStartClient(object obj)
    {
        // Ensure that we only start the client after the server has created the pipe
        ManualResetEvent SyncClientServer = (ManualResetEvent)obj;

        // Only continue after the server was created -- otherwise we just fail badly
        // SyncClientServer.WaitOne();

        using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "SAPipe"))
        {
            // The connect function will indefinately wait for the pipe to become available
            // If that is not acceptable specify a maximum waiting time (in ms)
            pipeStream.Connect();

            //Write from client to server
           using (StreamWriter sw = new StreamWriter(pipeStream))
            {
                sw.WriteLine("What's your status?");
           }

            //Read server reply
            /*using (StreamReader sr = new StreamReader(pipeStream))
            {
                string temp = "";
                temp = sr.ReadLine();   //Pipe is already closed here ... why?

                MessageBox.Show(temp);

            }*/

            //pipeStream.Close();

        }
    }
}

解决方案

Disposing of a StreamWriter or StreamReader will close the underlying stream.

Your using statements therefore will be causing the stream to close.

    public void ThreadStartClient(object obj)
    {
            // Ensure that we only start the client after the server has created the pipe
            ManualResetEvent SyncClientServer = (ManualResetEvent)obj;

            // Only continue after the server was created -- otherwise we just fail badly
            // SyncClientServer.WaitOne();

            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "SAPipe"))
            {
                // The connect function will indefinately wait for the pipe to become available
                // If that is not acceptable specify a maximum waiting time (in ms)
                pipeStream.Connect();


                //Write from client to server
                StreamWriter sw = new StreamWriter(pipeStream))
                sw.WriteLine("What's your status?");

                //Read server reply
                StreamReader sr = new StreamReader(pipeStream)
                string temp = "";
                temp = sr.ReadLine();   //Pipe is already closed here ... why?

                MessageBox.Show(temp);
            }
    }

It should also be noted that because you wrap your stream in a using statement, the commented out pipeStream.Close() function isn't needed.

这篇关于双向C ++到C#通信使用命名管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆