我使用命名管道将数据从客户端(C ++)传输到服务器(C#),客户端执行以下操作:
// C++ Client sending message
struct MESSAGE
{
char cCommand[8];
string sParameter;
};
MESSAGE msg;
strcpy(msg.cCommand, "COMMAND");
strcpy(msg.sParameter, "DO SOMETHING");
DWORD dwWrote = 0;
WriteFile (hpipe, &msg, sizeof(msg), dwWrote, NULL);
// Then, at the receiving end the C# server recieve message:
IntPtr chRequest;
bool fSuccess = ReadFile(hPipeInst, chRequest, uSize, cbRead, OverlappedPtr);
if (fSuccess)
byte[] temp = Encoding.ASCII.GetBytes(Marshal.PtrToStringAnsi(chRequest));
现在,在接收端,我需要将temp(byte [])转换回STRUCT或等效的东西,以便我可以访问成员cCommand和sPatameter - 但是在这一点上我不知道如何继续。 ..实际上不需要是一个结构,我只需要提取数据本身。
注意 - STRUCT MESSAGE是我提出的,这意味着如果不同的格式在重建中有用(例如添加sParameter的长度?),可以更改它,我只需要一个COMMAND和PARAMETER来被转移到一个区块(如果可能的话)。
要求很简单: - COMMAND是一个固定长度的8个字符长的字符串,表示需要执行的操作 - PARAMETER是一个可变长度(除非这会导致问题)参数依赖于每个COMMAND
例如: COMMAND = TRANS
PARAMETER = C:\ FILE.txt C:\ NewFolder \ FILE.TXT
(这只是为了说明,还有更多的应用程序)
如果可能的话,我想把它作为一大块数据(byte [])提取出来然后传递给我的应用程序,在那里它可以被分解,而不是读取大小的扇形,然后是字段,然后是大小,然后是一个字段 - 要求我的沟通与我的实现过度联系。
如果有更合适的方式来实施此转让请告诉我...欢迎提出建议...... 任何帮助将非常感激。 谢谢,
答案 0 :(得分:1)
在平台之间传递数据的建议 - 不要自己进行序列化/反序列化。像Google Protocol Buffers这样的图书馆将是一个更安全的赌注。
答案 1 :(得分:1)
如果你在c ++中有结构的定义,你可以在c#中定义它(它可能需要一点点)。然后只需读取套接字的大小并使用Marshal.PtrToStructure将其编组为c#定义的结构。
/* Define you structure like this (possibly) */
struct MESSAGE
{
[MarshalAs(UnmanageType.ByValArray, SizeConst=8)]
byte[] cCommand;
[MarshalAs(UnmanagedType.LPStr)]
string sParameter;
};
/* Read data into an instance of MESSAGE like this */
byte[] bytes = new byte[Marshal.SizeOf(MESSAGE)];
socket.Receive(bytes, 0, bytes.Length);
IntPtr ptr = Marshal.AllocHGlobal(bytes.Length);
try
{
Marshal.Copy(bytes, 0, ptr, bytes.Length);
m = (MESSAGE)Marshal.PtrToStructure(ptr, typeof(MESSAGE));
}
finally
{
Marshal.FreeHGlobal(ptr);
}
答案 2 :(得分:0)
.NET框架中有一个NamedPipeClientStream / NamedPipeServerStream类,它将对命名管道的访问作为Stream公开,这可以简化您正在做的事情。
传递数据的简单解决方案是使用基于行的协议,例如一行=一个带参数的命令:
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "testpipe", PipeDirection.In))
{
pipeClient.Connect();
using (StreamReader sr = new StreamReader(pipeClient))
{
string command;
while ((command = sr.ReadLine()) != null)
{
Console.WriteLine("Received command: {0}", command);
}
}
}