我有两个用c ++和c#编写的程序。我想在它们之间使用命名管道建立双向通信。 C#客户端程序可以连接到由c ++服务器程序创建的命名管道。但是两端都没有收到。
这是c ++部分(服务器):
#include <iostream>
#include <windows.h>
#include <stdlib.h>
#define UNICODE
using namespace std;
HANDLE hnamedPipe = INVALID_HANDLE_VALUE;
BOOL Finished =false;
HANDLE hThread = NULL;
unsigned long __stdcall CS_RcvThr(void * pParam) ;
int main(int argc, char **argv)
{
hnamedPipe = CreateNamedPipe(
"\\\\.\\pipe\\vikeyP",
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|
PIPE_READMODE_MESSAGE|
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if(hnamedPipe == INVALID_HANDLE_VALUE)
{
cout << "Failed" << endl;
}
while (true)
{
cout<< "Waiting for client"<< endl;
if(!ConnectNamedPipe(hnamedPipe,NULL))
{
if(ERROR_PIPE_CONNECTED != GetLastError())
{
cout << "FAIL"<< endl;
}
}
else
{
cout<<"Connected!"<<endl;
hThread = CreateThread( NULL, 0, &CS_RcvThr, NULL, 0, NULL);
if(hThread) cout<<"read thread created"<<endl; else cout<<"cant crat rd thed\n";
break;
}
}
while(1)
{
cout<<"lst loop"<<endl;
//Send over the message
char chResponse[] = "hello\n";
DWORD cbResponse,cbWritten;
cbResponse = sizeof(chResponse);
if (!WriteFile(
hnamedPipe,
chResponse,
cbResponse,
&cbWritten,
NULL))
{
wprintf(L"failiure w/err 0x%08lx\n",GetLastError);
}
cout<<"Sent bytes :)" << endl;
Sleep(10);
}
}
unsigned long __stdcall CS_RcvThr(void * pParam) {
BOOL fSuccess;
char chBuf[100];
DWORD dwBytesToWrite = (DWORD)strlen(chBuf);
DWORD cbRead;
int i;
while (1)
{
fSuccess =ReadFile( hnamedPipe,chBuf,dwBytesToWrite,&cbRead, NULL);
if (fSuccess)
{
printf("C++ App: Received %d Bytes : ",cbRead);
for(i=0;i<cbRead;i++)
printf("%c",chBuf[i]);
printf("\n");
}
if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
{
printf("Can't Read\n");
if(Finished)
break;
}
}
}
这是C#部分(客户端):
private Thread vikeyClientThread;
public void ThreadStartClient()
{
Console.WriteLine("Thread client started ID ={0} name = {1} " ,
Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.Name);
using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "vikeyP"))
{
// The connect function will indefinately wait for the pipe to become available
// If that is not acceptable specify a maximum waiting time (in ms)
Console.WriteLine("Connecting to ViKEY server...");
pipeStream.Connect();
Console.WriteLine("Connected :)");
//Write from client to server
StreamWriter sw = new StreamWriter(pipeStream);
while (true)
{
//Read server reply
StreamReader sr = new StreamReader(pipeStream);
string temp = "";
sw.WriteLine(System.DateTime.Now);
byte[] c = new byte[200];
temp = sr.ReadLine();
pipeStream.Read(c, 0, c.Length);
Console.WriteLine("RX =:{0}", Encoding.UTF8.GetString(c, 0, c.Length));
Thread.Sleep(500);
}
}
Console.WriteLine("Vikey pipe Closed");
Console.WriteLine("Thread with ID ={0} name = {1} is closed.",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name);
}
答案 0 :(得分:0)
您已将服务器端设置为消息类型与字节类型。如果要读取任意数量的字节,则需要使用名为pipe的字节类型。
您将流包装在一个StreamReader和一个StreamWriter的2个对象中。不要这样做,只需使用Stream。你试图逐行阅读,也不要这样做。而是发送要读取的字节数,后跟字节。在客户端,您将读取字节数,然后创建一个足够大的缓冲区,然后读取。如果它是文本数据,那么您将使用编码器(可能是ASCII)将其转换回C#字符串。
您的while(true)应该检测服务器何时关闭管道。
您应该考虑使用异步命名管道。