[英]C# c++ named pipes connection
I am trying to connect ac# project with a c++ project using named pipes but the c++ project doesn't connect. 我正在尝试使用命名管道将ac#项目与c ++项目连接,但是c ++项目无法连接。
ps: the .exe are both in the same file ps:.exe都在同一个文件中
side question: i don't understand the use of "\\\\.\\pipe\\" before my pipe name. 旁边的问题:我不知道在管道名称之前使用“ \\\\。\\ pipe \\”。 what does it do and it is really necesarry?
它是做什么的,真的是必需品吗?
Here's the my code maybe you can spot the error 这是我的代码,也许您可以发现错误
C# server: C#服务器:
Program.cs Program.cs
static class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
pipeHandler pipe = new pipeHandler();
var proc = new Process();
proc.StartInfo.FileName = "cplpltestpipes.exe";
proc.Start();
pipe.establishConnection();
Application.Run(new Form1(pipe));
}
}
public class pipeHandler
{
private StreamReader re;
private StreamWriter wr;
private NamedPipeServerStream pipeServer;
public void establishConnection()
{
pipeServer = new NamedPipeServerStream("myNamedPipe1");
pipeServer.WaitForConnection();
re = new StreamReader(pipeServer);
wr = new StreamWriter(pipeServer);
}
public void writePipe(string text)
{
wr.Write(text);
}
public string readPipe()
{
if(re.Peek()==-1)
System.Threading.Thread.Sleep(2000);
if (re.Peek() > -1)
{
string s;
s = re.ReadToEnd();
return s;
}
else
return "fail";
}
}
Form1.cs: Form1.cs:
public partial class Form1 : Form
{
pipeHandler pipePointer;
public Form1(pipeHandler pipe)
{
pipePointer=pipe;
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
pipePointer.writePipe(textBox1.Text);
textBox2.Text = pipePointer.readPipe();
}
}
c++ client C ++客户端
#define chrSize 16
int main()
{
TCHAR chr[chrSize];
DWORD bytesRead;
HANDLE pipeHandler;
LPTSTR pipeName = TEXT("\\\\.\\pipe\\myNamedPipe1");
pipeHandler = CreateFile(
pipeName, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
bool flag=false;
while (!flag)
{
flag = ConnectNamedPipe(pipeHandler, NULL);
cout << "trying";
}
ReadFile(
pipeHandler, // pipe handle
chr, // buffer to receive reply
chrSize * sizeof(TCHAR), // size of buffer
&bytesRead, // number of bytes read
NULL); // not overlapped
cout << chr;
LPTSTR pipeMessage = TEXT("message receive");
DWORD bytesToWrite= (lstrlen(pipeMessage) + 1) * sizeof(TCHAR);
DWORD cbWritten;
WriteFile(
pipeHandler, // pipe handle
pipeMessage, // message
bytesToWrite, // message length
&cbWritten, // bytes written
NULL); // not overlapped
CloseHandle(pipeHandler);
} }
Running the program just gives this exception in C# 运行程序只是在C#中给出了此异常
************** Exception Text ************** System.InvalidOperationException: Pipe hasn't been connected yet. **************异常文本************** System.InvalidOperationException:管道尚未连接。 .... .... ....
.... .... ....
and in c++ just keeps printing "trying" in console 并且在c ++中,始终在控制台中打印“ trying”
When you call CreateFile
how does CreateFile know that the object represented by the string myNamedPipe1
is a pipe? 当您调用
CreateFile
时, CreateFile
如何知道由字符串myNamedPipe1
表示的对象是管道? It knows because the name was prefixed with \\\\ServerName\\pipe\\
. 它知道,因为该名称以
\\\\ServerName\\pipe\\
为前缀。
In your case ServerName
can just be .
就您而言,
ServerName
可以是.
because that is a shortcut for "This machine", if you switch your code to LPTSTR pipeName = TEXT("\\\\\\\\.\\\\pipe\\\\myNamedPipe1");
因为这是“本机”的快捷方式,所以如果您将代码切换到
LPTSTR pipeName = TEXT("\\\\\\\\.\\\\pipe\\\\myNamedPipe1");
it should start working if there are no other issues. 如果没有其他问题,它应该开始工作。
you don't need to put it there in the C# code because the NamedPipeServerStream
class puts it there for you . 您不需要将其放在C#代码中,因为
NamedPipeServerStream
类为您放置了它 。
EDIT: Looking over your code, you may want to move pipeServer = new NamedPipeServerStream("myNamedPipe1");
编辑:查看您的代码,您可能想要移动
pipeServer = new NamedPipeServerStream("myNamedPipe1");
to the constructor of pipeHandler
, right now your C++ program may start up before the server is ever started, even if you had the correct name you still might get the error. 对于
pipeHandler
的构造pipeHandler
,现在即使您使用正确的名称,您的C ++程序也可能在服务器启动之前启动,即使您仍然使用正确的名称,也可能会收到错误消息。
EDIT2: ConnectNamedPipe
is the C++ equivalent of pipeServer.WaitForConnection();
编辑2:
ConnectNamedPipe
是pipeServer.WaitForConnection();
的C ++等效项pipeServer.WaitForConnection();
, you should not be doing that if the C++ program is the client. ,如果C ++程序是客户端,则不应这样做。 You should be good to go reading and writing as soon as you have a valid handle from
CreateFile
只要拥有
CreateFile
的有效句柄,就应该开始阅读和写作。
EDIT3: here is a example of how to rewrite the C# app to start the server up before starting the C++ app EDIT3:这是如何在启动C ++应用程序之前重写C#应用程序以启动服务器的示例
static class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//The server now gets created here.
pipeHandler pipe = new pipeHandler();
var proc = new Process();
proc.StartInfo.FileName = "cplpltestpipes.exe";
proc.Start();
//The server used to be created here.
pipe.EstablishConnection();
Application.Run(new Form1(pipe));
}
}
public class pipeHandler
{
private StreamReader re;
private StreamWriter wr;
private NamedPipeServerStream pipeServer;
public pipeHandler()
{
//We now create the server in the constructor.
pipeServer = new NamedPipeServerStream("myNamedPipe1");
}
public void establishConnection()
{
pipeServer.WaitForConnection();
re = new StreamReader(pipeServer);
wr = new StreamWriter(pipeServer);
}
...
}
Then in your C++ code delete 然后在您的C ++代码中删除
while (!flag)
{
flag = ConnectNamedPipe(pipeHandler, NULL);
cout << "trying";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.