我正在努力在C#和C ++之间进行沟通,取得了不同程度的成功。
我可以使用回复/请求在两者之间发送消息,但我收到的双打不正确。
出于调试目的和理解,我目前正在运行以下内容:
Clrzmq 3.0 rc1,Google ProtocolBuffer 2.5,Protobuf-csharp-port-2.4,ZeroMQ-3.2.3
.Proto
package InternalComm;
message Point
{
optional double x = 1;
optional double y = 2;
optional string label = 3;
}
server.cpp(相关部分)
while (true) {
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
zmq::message_t reply (request.size());
memcpy ((void*)reply.data(), request.data(), request.size());
socket.send(reply);
}
client.cs(相关部分)
public static Point ProtobufPoint(Point point)
{
Point rtn = new Point(0,0);
using (var context = ZmqContext.Create())
{
using (ZmqSocket requester = context.CreateSocket(SocketType.REQ))
{
requester.Connect("tcp://localhost:5555");
var p = InternalComm.Point.CreateBuilder().SetX(point.X).SetY(point.Y).Build().ToByteArray();
requester.Send(p);
string reply = requester.Receive(Encoding.ASCII);
Console.WriteLine("Input: {0}", point);
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(reply);
var message = InternalComm.Point.ParseFrom(bytes);
rtn.X = message.X;
rtn.Y = message.Y;
Console.WriteLine("Output: {0}", rtn);
}
}
return rtn;
}
在C#方面,Point是一个非常简单的结构。只是x和y属性。
以下是运行上述代码后我从单元测试中得到的结果。
输入(1.31616874365468,4.55516872325469)
输出(0.000473917985115791,4.55516872323627)
输入(274.120398471829,274.128936418736)
产出(274.077917334613,274.128936049925)输入(150.123798461987,2.345E-12)
产出(145.976459594794,1.11014954927532E-13)输入(150,0)
输出(145.96875,0)
我认为问题是我的protobuf代码不正确(怀疑这是Skeet方面的错误)。我也假设server.cpp对消息没有任何作用,但按原样返回。
思想?
答案 0 :(得分:4)
为什么选择ASCII - > bytes - >解析步骤?如果要解析字节,则应该读取字节。如果你正在解析文本,你应该阅读它。
不必要的字符集转换看起来很可能是错误的。
答案 1 :(得分:4)
requestor.Receive(Encoding.ASCII)
调用旨在接收字符串,而不是字节块。您要求ZmqSocket
实例将消息作为ASCII字符串返回,这极有可能导致对内容的修改。如果要发送字节数组,则接收字节数组。
试试这个:
int readSize;
byte[] reply = requester.Receive(null, out readSize);
var message = InternalComm.Point.ParseFrom(reply);
readSize
变量将包含接收块中的实际有效字节数,这可能与reply
数组的大小不同,因此您可能需要对阵列进行切片以使其成为可能适合ProtoBuf。